<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/113884>113884</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [clang] alignment attribute constrained by #pragma pack is inconsistent with the actual alignment in the IR
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          mzyx-hnu
      </td>
    </tr>
</table>

<pre>
    In this case, I used #pragma pack to set the structure alignment to 1. Then, I loaded the first int member of the structure. When compiled with -O2, the align attribute in the IR was converted to 4. 

~~~
// align.c
#pragma pack(1)
struct a {
  volatile int b;
  int c;
  long d;
  long e;
  short f;
unsigned : 25;
  volatile long g;
  int h;
} i[];

static volatile struct a k = {1}, l = {2}, m = {3}, n = {4}, p = {5}, q = {6};

static int foo() {
  int s = m.b;                                                 // load m with align 4
  m.c = k.c = l.c = n.c = p.c = q.c = 1;
  return s;
}

int main() {
  foo();
  return 0;
}
~~~
compile with `-O2 -emit-llvm -S`
~~~
; ModuleID = './align.c'
source_filename = "./align.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"
target triple = "aarch64-unknown-linux-gnu"

%struct.a = type <{ i32, i32, i64, i64, i16, i32, i64, i32 }>

@i = dso_local local_unnamed_addr global [1 x %struct.a] zeroinitializer, align 1
@m = internal global <{ i32, i32, i64, i64, i16, [4 x i8], i64, i32 }> <{ i32 3, i32 0, i64 0, i64 0, i16 0, [4 x i8] zeroinitializer, i64 0, i32 0 }>, align 4
@q = internal global <{ i32, i32, i64, i64, i16, [4 x i8], i64, i32 }> <{ i32 6, i32 0, i64 0, i64 0, i16 0, [4 x i8] zeroinitializer, i64 0, i32 0 }>, align 1
@p = internal global <{ i32, i32, i64, i64, i16, [4 x i8], i64, i32 }> <{ i32 5, i32 0, i64 0, i64 0, i16 0, [4 x i8] zeroinitializer, i64 0, i32 0 }>, align 1
@n = internal global <{ i32, i32, i64, i64, i16, [4 x i8], i64, i32 }> <{ i32 4, i32 0, i64 0, i64 0, i16 0, [4 x i8] zeroinitializer, i64 0, i32 0 }>, align 1
@l = internal global <{ i32, i32, i64, i64, i16, [4 x i8], i64, i32 }> <{ i32 2, i32 0, i64 0, i64 0, i16 0, [4 x i8] zeroinitializer, i64 0, i32 0 }>, align 1
@k = internal global <{ i32, i32, i64, i64, i16, [4 x i8], i64, i32 }> <{ i32 1, i32 0, i64 0, i64 0, i16 0, [4 x i8] zeroinitializer, i64 0, i32 0 }>, align 1

; Function Attrs: nofree norecurse nounwind memory(readwrite, argmem: none) uwtable
define dso_local noundef i32 @main() local_unnamed_addr #0 {
entry:
  %0 = load volatile i32, ptr @m, align 4, !tbaa !6
  store volatile i32 1, ptr getelementptr inbounds nuw (i8, ptr @q, i64 4), align 1, !tbaa !13
  store volatile i32 1, ptr getelementptr inbounds nuw (i8, ptr @p, i64 4), align 1, !tbaa !13
  store volatile i32 1, ptr getelementptr inbounds nuw (i8, ptr @n, i64 4), align 1, !tbaa !13
  store volatile i32 1, ptr getelementptr inbounds nuw (i8, ptr @l, i64 4), align 1, !tbaa !13
  store volatile i32 1, ptr getelementptr inbounds nuw (i8, ptr @k, i64 4), align 1, !tbaa !13
  store volatile i32 1, ptr getelementptr inbounds nuw (i8, ptr @m, i64 4), align 4, !tbaa !13
  ret i32 0
}
~~~

The pass responsible for increasing the alignment attribute is InferAlignmentPass. Since the user code loaded the structure object m with a 4-byte alignment once, the alignment attribute for m was increased from 1 to 4. However, the structure's actual memory layout does not adhere to 4-byte alignment, and this inconsistency has caused issues in my development. Should llvm add a check in InferAlignmentPass for this case?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEWEGP47oN_jXKhXBgy07sHHLIbF7QORSv6D6gx4VsM7E6suSR5MlkD_vbC0m242RmgRYoMjlYEUWR_EhaJsWM4SeJuCWrJ7LaL1hvG6W37c_Le9TIflGq-rJ9lmAbbqBiBgn9Bs_QG6yB0LTT7NQy6Fj1AlaBQQu2QTBW95XtNQIT_CRblNYtJ0v4q0EZRAjFaqw9-5FrY4FLCy22JWpQx1sxS_hXgxIq1XZcYA1nbhuI_qROkmP0WoBZq3nZWwQuPfn5n3BmBiol31Bbp0xBtgQS70m8C89fv34NU3og9BAkLauRNgdIaJEQuglLwTRgQPKnQAF4U4JZLtAjKUk6Lbh5NZsLJU9Q3xNwRjCN0haOE6WXPkw1kHQHdDXjnJR6Gac7rc00J_keeAjylTZAYZZXV0ETtBcg6d4BTEi-d64WI4EOhHYkpANBjoRsIHQjYTUQXkfC2hE-tcQZflSK0ILQzdzBbsH4_e3S-Rf-198QZJd60IYsCqmTjSraZeUVvAyjGEY5jN0wvg5jMnO4RttrCWbu8zk8n-CMy4_AJrQfpcUfpU05O7wPAQhZx9GfFCJsuY2EeGsh-k7W8X2ap0_wd1X3Ap_3IRI0XxJ6GPOe5kMoVK8r_HHkAiVrcWClN6w0sFqmT2ihZpYJdlG9HZkxakm6w6ijeUzSXUr9w02T26n7t878I-IFSXdFWOLJmqQ7_3CziSWhjiGhRSTTsDf67mYHN70zy2reicl-xnTVrLOoly9SnWUkuOzfo5Psp23jm78Kr8GS-a320jkZ30j-BDz15844rLP5kKw_WUsp-GT_40ZFFnMvuzbqh1AVE-CfP3rpPF7_YHWt4SRUyQSQ1VMC7zAzi6z28BO14pJbzgT_idrpCumcTCrCG8qlRS2ZmMT910jI6imDd-CFOzc-gzSTBem4FA-s93-Sdfgzl_oZiusOJ2x03gQvm-C9PhLe-kHwrtHrHglv9XB48pHwsofDE4-ERx8O7-WR8JIHw5s-lodeVpYrCTtrtXHll1RHjQhSaax6bdy_Xp65rF31qvSF0EIjq8-aW18tM31qsQ07Jbovf3-2rBQYlNR45BJnXwEnrsZjcEQWzyqGT74PhKbxtZJAafWFpLuxhiB0FYcyxlU81_o0RKWz2iuYH6zOgzSxJWNuXE_1qFUabwSEiDgRJ7Qo0NX4bsZl6ew3IPszEFrwYqbqdYxA5mqdmdNv1Sbp_1lv90V65RfpFV-k9-WL9Laf671P56tejXY4TX5TWofnXw1Cx4wBjaZT0vBSIByVs6bSyAyXp2v_6bvcWQ9q4FkeUe_GtX8wY5bwncsK_abeoIZK1Thvha-dsyr_jZWd2hTIovJi56qUrPz58jsDnJ2tb4AHa7GGo1YtJEMf_Dd1xrdwKt6oJjQ3wCrbMzEcaTAU9rVCA1JZYHWDGr2cO7O892UdLgy4rJzXjEVZXaBxvTjzVwfcmB7dOrQXqPENherc7iV8b1QvavANDKtrYFA1WL041o_u9BivVxN_HMjTN7I5LOptWm_SDVvgNsnTOInXWZYvmm0R05imcU6rjBYlXa0Ldqzqqsgxw9UmZwu-pTHNkpgW8SbOab5kWVZu8mR9LMs4LzYxyWJsGRdLZ-BS6dPCQ9kmSVoU2UKwEoXxlymUVoLJk2ssVvuF3roNUdmfjHs_ubHmKsJyK_wNTNix2n8aT-dKqxmXWEN5ub99ufW2DVnjUyME8ipxuhxZ9FpsG2s791kLrfGJ26Yvl5VqCT04-4Yh6rRy6UjoIYSO0MMA-W1L_xMAAP__9nsx9g">