llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clangir

Author: Sirui Mu (Lancern)

<details>
<summary>Changes</summary>

This patch contains the following changes:

- It adds two optional attributes to the `cir.copy` operation, namely 
`src_alignment` and `dst_alignment`. They give the alignment of the source 
pointer and the destination pointer.
- It updates the LLVM lowering pass and attaches alignment information to the 
`llvm.memcpy` operation lowered from `cir.copy` operation. If `src_alignment` 
or `dst_alignment` is missing, the default alignment of the pointee type is 
used instead.
- Tests are updated accordingly.

There is one revealed mismatch between LLVM and OGCG checks after this update, 
at `clang/test/CIR/CodeGen/array.cpp:482`. The corresponding `cir.CopyOp` is 
created at `clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp:2244`, which 
currently lacks special handling for pointer alignments.

Assisted-by: Codex / gpt-5.5 xhigh

---

Patch is 84.60 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/206341.diff


43 Files Affected:

- (modified) clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h (+3-2) 
- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+9-3) 
- (modified) clang/lib/CIR/CodeGen/CIRGenBuilder.h (+10) 
- (modified) clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp (+1-2) 
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+21-1) 
- (modified) clang/test/CIR/CodeGen/abstract-cond.c (+10-10) 
- (modified) clang/test/CIR/CodeGen/agg-atomic-cast.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/agg-expr-lvalue.c (+2-2) 
- (modified) clang/test/CIR/CodeGen/aggregate-copy-overlap.cpp (+4-4) 
- (modified) clang/test/CIR/CodeGen/array.cpp (+6-6) 
- (modified) clang/test/CIR/CodeGen/atomic-libcall.c (+2-2) 
- (modified) clang/test/CIR/CodeGen/binassign.c (+4-4) 
- (modified) clang/test/CIR/CodeGen/complex-cast.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGen/compound_literal.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGen/consteval-aggregate.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/copy-constructor.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/embed-expr.c (+1-1) 
- (modified) clang/test/CIR/CodeGen/global-decomp-decls.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/lambda.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/local-const-aggregate-name-clash.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/loop.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGen/no-odr-use.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGen/no-unique-address.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/nrvo.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGen/paren-init-list.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGen/paren-list-agg-init.cpp (+18-18) 
- (modified) clang/test/CIR/CodeGen/pointer-to-member-func.cpp (+3-3) 
- (modified) clang/test/CIR/CodeGen/statement-exprs.c (+3-3) 
- (modified) clang/test/CIR/CodeGen/static-local.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGen/struct-init.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGen/struct.cpp (+12-12) 
- (modified) clang/test/CIR/CodeGen/temp-param-obj-decl.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGen/three-way-cmp.cpp (+8-8) 
- (modified) clang/test/CIR/CodeGen/var-arg-aggregate.c (+2-2) 
- (modified) clang/test/CIR/CodeGen/variable-decomposition.cpp (+1-1) 
- (modified) clang/test/CIR/CodeGenCXX/new-array-init.cpp (+9-9) 
- (modified) clang/test/CIR/CodeGenCXX/sizeof-pack.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGenOpenACC/combined-firstprivate-clause.cpp 
(+6-6) 
- (modified) 
clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause-templates.cpp (+2-2) 
- (modified) clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause.c (+2-2) 
- (modified) clang/test/CIR/CodeGenOpenACC/compute-firstprivate-clause.cpp 
(+6-6) 
- (modified) clang/test/CIR/CodeGenOpenACC/firstprivate-clause-recipes.cpp 
(+3-3) 
- (modified) clang/test/CIR/Lowering/array.cpp (+5-5) 


``````````diff
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index e1a5561ae11e1..f8a3aca76f102 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -377,8 +377,9 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
   cir::CopyOp createCopy(mlir::Value dst, mlir::Value src,
                          bool isVolatile = false,
                          bool skipTailPadding = false) {
-    return cir::CopyOp::create(*this, dst.getLoc(), dst, src, isVolatile,
-                               skipTailPadding);
+    return cir::CopyOp::create(*this, dst.getLoc(), dst, src,
+                               /*dst_alignment=*/{}, /*src_alignment=*/{},
+                               isVolatile, skipTailPadding);
   }
 
   cir::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value 
dst,
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 7d1c48b994b27..67f81e44db0c0 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4616,13 +4616,19 @@ def CIR_CopyOp : CIR_Op<"copy",[
   let arguments = (ins
       Arg<CIR_PointerType, "", [MemWrite]>:$dst,
       Arg<CIR_PointerType, "", [MemRead]>:$src,
+      OptionalAttr<I64Attr>:$dst_alignment,
+      OptionalAttr<I64Attr>:$src_alignment,
       UnitAttr:$is_volatile,
       UnitAttr:$skip_tail_padding
   );
 
-  let assemblyFormat = [{$src `to` $dst (`volatile` $is_volatile^)?
-                        (`skip_tail_padding` $skip_tail_padding^)?
-                        attr-dict `:` qualified(type($dst))
+  let assemblyFormat = [{
+    $src (`align` `(` $src_alignment^ `)`)?
+    `to`
+    $dst (`align` `(` $dst_alignment^ `)`)?
+    (`volatile` $is_volatile^)?
+    (`skip_tail_padding` $skip_tail_padding^)?
+    attr-dict `:` qualified(type($dst))
   }];
   let hasVerifier = 1;
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h 
b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index cc1ff1e32521f..1de0e5e3bb8cb 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -239,6 +239,16 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
   // Operation creation helpers
   // --------------------------
   //
+  using CIRBaseBuilderTy::createCopy;
+  cir::CopyOp createCopy(Address dst, Address src, bool isVolatile = false,
+                         bool skipTailPadding = false) {
+    cir::CopyOp op = createCopy(dst.getPointer(), src.getPointer(), isVolatile,
+                                skipTailPadding);
+    op.setDstAlignment(dst.getAlignment().getQuantity());
+    op.setSrcAlignment(src.getAlignment().getQuantity());
+    return op;
+  }
+
   cir::MemCpyOp createMemCpy(mlir::Location loc, mlir::Value dst,
                              mlir::Value src, mlir::Value len) {
     return cir::MemCpyOp::create(*this, loc, dst, src, len);
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index 4d54519e4d25f..fcccf6f8c5f68 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -1337,8 +1337,7 @@ void CIRGenFunction::emitAggregateCopy(LValue dest, 
LValue src, QualType ty,
   // NOTE(cir): original codegen would normally convert destPtr and srcPtr to
   // i8* since memcpy operates on bytes. We don't need that in CIR because
   // cir.copy will operate on any CIR pointer that points to a sized type.
-  builder.createCopy(destPtr.getPointer(), srcPtr.getPointer(), isVolatile,
-                     skipTailPadding);
+  builder.createCopy(destPtr, srcPtr, isVolatile, skipTailPadding);
 
   assert(!cir::MissingFeatures::opTBAA());
 }
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index e0fc9e58ed4b7..69f2c7ebd0fb5 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -216,8 +216,28 @@ mlir::LogicalResult 
CIRToLLVMCopyOpLowering::matchAndRewrite(
       rewriter, op.getLoc(), rewriter.getI64Type(),
       op.getCopySizeInBytes(layout));
   assert(!cir::MissingFeatures::aggValueSlotVolatile());
+
+  uint64_t dstTypeAlign = dataLayout.getTypeABIAlignment(convertTypeForMemory(
+      *getTypeConverter(), dataLayout, op.getDst().getType().getPointee()));
+  uint64_t srcTypeAlign = dataLayout.getTypeABIAlignment(convertTypeForMemory(
+      *getTypeConverter(), dataLayout, op.getSrc().getType().getPointee()));
+
+  mlir::NamedAttribute dstAlignAttr = rewriter.getNamedAttr(
+      mlir::LLVM::LLVMDialect::getAlignAttrName(),
+      rewriter.getI64IntegerAttr(op.getDstAlignment().value_or(dstTypeAlign)));
+  mlir::NamedAttribute srcAlignAttr = rewriter.getNamedAttr(
+      mlir::LLVM::LLVMDialect::getAlignAttrName(),
+      rewriter.getI64IntegerAttr(op.getSrcAlignment().value_or(srcTypeAlign)));
+  mlir::ArrayAttr argAttrs = rewriter.getArrayAttr({
+      /*dst_attrs=*/rewriter.getDictionaryAttr({dstAlignAttr}),
+      /*src_attrs=*/rewriter.getDictionaryAttr({srcAlignAttr}),
+  });
+
   rewriter.replaceOpWithNewOp<mlir::LLVM::MemcpyOp>(
-      op, adaptor.getDst(), adaptor.getSrc(), length, op.getIsVolatile());
+      op, adaptor.getDst(), adaptor.getSrc(), length, op.getIsVolatile(),
+      /*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
+      /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr, /*arg_attrs=*/argAttrs,
+      /*res_attrs=*/nullptr);
   return mlir::success();
 }
 
diff --git a/clang/test/CIR/CodeGen/abstract-cond.c 
b/clang/test/CIR/CodeGen/abstract-cond.c
index 00008ea876b7b..98fa2ac8dc0f4 100644
--- a/clang/test/CIR/CodeGen/abstract-cond.c
+++ b/clang/test/CIR/CodeGen/abstract-cond.c
@@ -19,9 +19,9 @@ int test_agg_cond(int a0, struct s6 a1, struct s6 a2) {
 // CIR:  %[[LOAD_A0:.*]] = cir.load{{.*}} %[[A0]] : !cir.ptr<!s32i>, !s32i
 // CIR:  %[[COND:.*]] = cir.cast int_to_bool %[[LOAD_A0]] : !s32i -> !cir.bool
 // CIR:  cir.if %[[COND]] {
-// CIR:    cir.copy %[[A1]] to %[[TMP]] : !cir.ptr<!rec_s6>
+// CIR:    cir.copy %[[A1]] align(4) to %[[TMP]] align(4) : !cir.ptr<!rec_s6>
 // CIR:  } else {
-// CIR:    cir.copy %[[A2]] to %[[TMP]] : !cir.ptr<!rec_s6>
+// CIR:    cir.copy %[[A2]] align(4) to %[[TMP]] align(4) : !cir.ptr<!rec_s6>
 // CIR:  }
 // CIR:  cir.get_member %[[TMP]][0] {name = "f0"} : !cir.ptr<!rec_s6> -> 
!cir.ptr<!s32i>
 
@@ -30,10 +30,10 @@ int test_agg_cond(int a0, struct s6 a1, struct s6 a2) {
 // LLVM:    %[[COND:.*]] = icmp ne i32 %[[LOAD_A0]], 0
 // LLVM:    br i1 %[[COND]], label %[[A1_PATH:.*]], label %[[A2_PATH:.*]]
 // LLVM:  [[A1_PATH]]:
-// LLVM:    call void @llvm.memcpy.p0.p0.i64(ptr %[[TMP:.*]], ptr {{.*}}, i64 
4, i1 false)
+// LLVM:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[TMP:.*]], ptr 
align 4 {{.*}}, i64 4, i1 false)
 // LLVM:    br label %[[EXIT:.*]]
 // LLVM:  [[A2_PATH]]:
-// LLVM:    call void @llvm.memcpy.p0.p0.i64(ptr %[[TMP]], ptr {{.*}}, i64 4, 
i1 false)
+// LLVM:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[TMP]], ptr align 4 
{{.*}}, i64 4, i1 false)
 // LLVM:    br label %[[EXIT]]
 // LLVM:  [[EXIT]]:
 // LLVM:    getelementptr {{.*}}, ptr %[[TMP]], i32 0, i32 0
@@ -70,12 +70,12 @@ int test_stmt_expr(int flag, struct s6 a1, struct s6 a2) {
 // CIR:    %[[STMT_TMP:.*]] = cir.alloca "tmp" {{.*}} : !cir.ptr<!rec_s6>
 // CIR:    cir.scope {
 // CIR:      %[[T:.*]] = cir.alloca "t" {{.*}} init : !cir.ptr<!rec_s6>
-// CIR:      cir.copy %[[A1]] to %[[T]] : !cir.ptr<!rec_s6>
+// CIR:      cir.copy %[[A1]] align(4) to %[[T]] align(4) : !cir.ptr<!rec_s6>
 // CIR:      cir.call @foo() : () -> ()
-// CIR:      cir.copy %[[T]] to %[[TMP]] : !cir.ptr<!rec_s6>
+// CIR:      cir.copy %[[T]] align(4) to %[[TMP]] align(4) : !cir.ptr<!rec_s6>
 // CIR:    }
 // CIR:  } else {
-// CIR:    cir.copy %[[A2]] to %[[TMP]] : !cir.ptr<!rec_s6>
+// CIR:    cir.copy %[[A2]] align(4) to %[[TMP]] align(4) : !cir.ptr<!rec_s6>
 // CIR:  }
 // CIR:  cir.get_member %[[TMP]][0] {name = "f0"} : !cir.ptr<!rec_s6> -> 
!cir.ptr<!s32i>
 
@@ -86,14 +86,14 @@ int test_stmt_expr(int flag, struct s6 a1, struct s6 a2) {
 // LLVM:  [[TRUE]]:
 // LLVM:    br label %[[STMT_BODY:.*]]
 // LLVM:  [[STMT_BODY]]:
-// LLVM:    call void @llvm.memcpy.p0.p0.i64(ptr %[[T:.*]], ptr {{.*}}, i64 4, 
i1 false)
+// LLVM:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[T:.*]], ptr align 
4 {{.*}}, i64 4, i1 false)
 // LLVM:    call void @foo()
-// LLVM:    call void @llvm.memcpy.p0.p0.i64(ptr %[[TMP:.*]], ptr %[[T]], i64 
4, i1 false)
+// LLVM:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[TMP:.*]], ptr 
align 4 %[[T]], i64 4, i1 false)
 // LLVM:    br label %[[JOIN_FROM_TRUE:.*]]
 // LLVM:  [[JOIN_FROM_TRUE]]:
 // LLVM:    br label %[[EXIT:.*]]
 // LLVM:  [[FALSE]]:
-// LLVM:    call void @llvm.memcpy.p0.p0.i64(ptr %[[TMP]], ptr {{.*}}, i64 4, 
i1 false)
+// LLVM:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[TMP]], ptr align 4 
{{.*}}, i64 4, i1 false)
 // LLVM:    br label %[[EXIT]]
 // LLVM:  [[EXIT]]:
 // LLVM:    getelementptr inbounds nuw %struct.s6, ptr %[[TMP]], i32 0, i32 0
diff --git a/clang/test/CIR/CodeGen/agg-atomic-cast.cpp 
b/clang/test/CIR/CodeGen/agg-atomic-cast.cpp
index 12ed04f14edf2..450ad8752ef8f 100644
--- a/clang/test/CIR/CodeGen/agg-atomic-cast.cpp
+++ b/clang/test/CIR/CodeGen/agg-atomic-cast.cpp
@@ -16,11 +16,11 @@ void non_atomic_to_atomic_cast() {
 
 // CIR: %[[S_ADDR:.*]] = cir.alloca "s" {{.*}} : !cir.ptr<!rec_S>
 // CIR: %[[SA_ADDR:.*]] = cir.alloca "as" {{.*}} init : !cir.ptr<!rec_S>
-// CIR: cir.copy %[[S_ADDR]] to %[[SA_ADDR]] : !cir.ptr<!rec_S>
+// CIR: cir.copy %[[S_ADDR]] align(4) to %[[SA_ADDR]] align(16) : 
!cir.ptr<!rec_S>
 
 // LLVM:  %[[S_ADDR:.*]] = alloca %struct.S, i64 1, align 4
 // LLVM: %[[SA_ADDR:.*]] = alloca %struct.S, i64 1, align 16
-// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[SA_ADDR]], ptr %[[S_ADDR]], 
i64 16, i1 false)
+// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr align 16 %[[SA_ADDR]], ptr align 
4 %[[S_ADDR]], i64 16, i1 false)
 
 // OGCG: %[[S_ADDR:.*]] = alloca %struct.S, align 4
 // OGCG: %[[SA_ADDR:.*]] = alloca %struct.S, align 16
diff --git a/clang/test/CIR/CodeGen/agg-expr-lvalue.c 
b/clang/test/CIR/CodeGen/agg-expr-lvalue.c
index 51109d3082ab0..0470f803e4f2b 100644
--- a/clang/test/CIR/CodeGen/agg-expr-lvalue.c
+++ b/clang/test/CIR/CodeGen/agg-expr-lvalue.c
@@ -37,7 +37,7 @@ void test_member_in_array(void) {
 // LLVM-LABEL: define{{.*}} @test_member_in_array
 // LLVM:   %[[LINE:.*]] = alloca %struct.Line
 // LLVM:   %[[ARR:.*]] = alloca [1 x %struct.Point]
-// LLVM:   call void @llvm.memcpy{{.*}}(ptr %[[LINE]], ptr @[[LINE_CONST]]
+// LLVM:   call void @llvm.memcpy{{.*}}(ptr align 4 %[[LINE]], ptr align 4 
@[[LINE_CONST]]
 // LLVM:   %[[MEMBER:.*]] = 
getelementptr{{.*}}%struct.Line{{.*}}%[[LINE]]{{.*}}i32 0, i32 0
 // LLVM:   call void @llvm.memcpy
 
@@ -111,7 +111,7 @@ void test_string_array_in_array(void) {
 
 // LLVM-LABEL: define{{.*}} @test_string_array_in_array
 // LLVM:   %[[MATRIX:.*]] = alloca [2 x [6 x i8]]
-// LLVM:   call void @llvm.memcpy{{.*}}(ptr %[[MATRIX]], ptr @[[MATRIX_CONST]]
+// LLVM:   call void @llvm.memcpy{{.*}}(ptr align 1 %[[MATRIX]], ptr align 1 
@[[MATRIX_CONST]]
 
 // OGCG-LABEL: define{{.*}} @test_string_array_in_array
 // OGCG:   alloca [2 x [6 x i8]]
diff --git a/clang/test/CIR/CodeGen/aggregate-copy-overlap.cpp 
b/clang/test/CIR/CodeGen/aggregate-copy-overlap.cpp
index 4b60feba2c0d7..985ee6b1f75ad 100644
--- a/clang/test/CIR/CodeGen/aggregate-copy-overlap.cpp
+++ b/clang/test/CIR/CodeGen/aggregate-copy-overlap.cpp
@@ -35,11 +35,11 @@ struct Outer : virtual VBase {
 
 // With virtual bases, only the C1 (complete) constructor is emitted.
 // CIR-LABEL: cir.func {{.*}} @_ZN5OuterC1ERK10HasPaddingc(
-// CIR:         cir.copy %{{.+}} to %{{.+}} skip_tail_padding : 
!cir.ptr<!rec_HasPadding>
+// CIR:         cir.copy %{{.+}} align(4) to %{{.+}} align(8) 
skip_tail_padding : !cir.ptr<!rec_HasPadding>
 
 // LLVM-LABEL: define {{.*}} void @_ZN5OuterC1ERK10HasPaddingc(
 // LLVM:         %[[GEP:.*]] = getelementptr inbounds nuw %struct.Outer, ptr 
%{{.+}}, i32 0, i32 1
-// LLVM:         call void @llvm.memcpy.p0.p0.i64(ptr %[[GEP]], ptr %{{.+}}, 
i64 5, i1 false)
+// LLVM:         call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[GEP]], ptr 
align 4 %{{.+}}, i64 5, i1 false)
 
 // OGCG-LABEL: define {{.*}} void @_ZN5OuterC1ERK10HasPaddingc(
 // OGCG:         %[[GEP:.*]] = getelementptr inbounds nuw %struct.Outer, ptr 
%{{.+}}, i32 0, i32 1
@@ -58,11 +58,11 @@ struct NonOverlapping {
 };
 
 // CIR-LABEL: cir.func {{.*}} @_ZN14NonOverlappingC2ERK10HasPaddingc(
-// CIR:         cir.copy %{{.+}} to %{{.+}} : !cir.ptr<!rec_HasPadding>
+// CIR:         cir.copy %{{.+}} align(4) to %{{.+}} align(4) : 
!cir.ptr<!rec_HasPadding>
 
 // LLVM-LABEL: define {{.*}} void @_ZN14NonOverlappingC2ERK10HasPaddingc(
 // LLVM:         %[[GEP:.*]] = getelementptr inbounds nuw 
%struct.NonOverlapping, ptr %{{.+}}, i32 0, i32 0
-// LLVM:         call void @llvm.memcpy.p0.p0.i64(ptr %[[GEP]], ptr %{{.+}}, 
i64 8, i1 false)
+// LLVM:         call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[GEP]], ptr 
align 4 %{{.+}}, i64 8, i1 false)
 
 // OGCG-LABEL: define {{.*}} void @_ZN14NonOverlappingC2ERK10HasPaddingc(
 // OGCG:         %[[GEP:.*]] = getelementptr inbounds nuw 
%struct.NonOverlapping, ptr %{{.+}}, i32 0, i32 0
diff --git a/clang/test/CIR/CodeGen/array.cpp b/clang/test/CIR/CodeGen/array.cpp
index 5d288ad91a576..d3149988b3213 100644
--- a/clang/test/CIR/CodeGen/array.cpp
+++ b/clang/test/CIR/CodeGen/array.cpp
@@ -187,7 +187,7 @@ void func2() {
 
 // LLVM: define{{.*}} void @_Z5func2v(){{.*}}
 // LLVM:   %[[ARR:.*]] = alloca [2 x i32], i64 1, align 4
-// LLVM:   call void @llvm.memcpy.p0.p0.i64(ptr %[[ARR]], ptr 
@[[FUNC2_ARR:.*]], i64 8, i1 false)
+// LLVM:   call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[ARR]], ptr align 4 
@[[FUNC2_ARR:.*]], i64 8, i1 false)
 
 // OGCG: %[[ARR:.*]] = alloca [2 x i32], align 4
 // OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[ARR]], ptr align 4 
@[[FUN2_ARR]], i64 8, i1 false)
@@ -216,7 +216,7 @@ void func3() {
 // LLVM:  %[[ARR:.*]] = alloca [2 x i32], i64 1, align 4
 // LLVM:  %[[IDX:.*]] = alloca i32, i64 1, align 4
 // LLVM:  %[[INIT:.*]] = alloca i32, i64 1, align 4
-// LLVM:  call void @llvm.memcpy.p0.p0.i64(ptr %[[ARR]], ptr 
@[[FUNC3_ARR:.*]], i64 8, i1 false)
+// LLVM:  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[ARR]], ptr align 4 
@[[FUNC3_ARR:.*]], i64 8, i1 false)
 // LLVM:  store i32 1, ptr %[[IDX]], align 4
 // LLVM:  %[[TMP1:.*]] = load i32, ptr %[[IDX]], align 4
 // LLVM:  %[[IDX_I64:.*]] = sext i32 %[[TMP1]] to i64
@@ -254,7 +254,7 @@ void func4() {
 // LLVM: define{{.*}} void @_Z5func4v(){{.*}}
 // LLVM:  %[[ARR:.*]] = alloca [2 x [1 x i32]], i64 1, align 4
 // LLVM:  %[[INIT:.*]] = alloca i32, i64 1, align 4
-// LLVM:  call void @llvm.memcpy.p0.p0.i64(ptr %[[ARR]], ptr 
@[[FUNC4_ARR:.*]], i64 8, i1 false)
+// LLVM:  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[ARR]], ptr align 4 
@[[FUNC4_ARR:.*]], i64 8, i1 false)
 // LLVM:  %[[ARR_1:.*]] = getelementptr [2 x [1 x i32]], ptr %[[ARR]], i32 0, 
i64 1
 // LLVM:  %[[ELE_PTR:.*]] = getelementptr [1 x i32], ptr %[[ARR_1]], i32 0, 
i64 0
 // LLVM:  %[[TMP:.*]] = load i32, ptr %[[ELE_PTR]], align 4
@@ -278,7 +278,7 @@ void func5() {
 
 // LLVM: define{{.*}} void @_Z5func5v(){{.*}}
 // LLVM:   %[[ARR:.*]] = alloca [2 x [1 x i32]], i64 1, align 4
-// LLVM:   call void @llvm.memcpy.p0.p0.i64(ptr %[[ARR]], ptr 
@[[FUNC5_ARR:.*]], i64 8, i1 false)
+// LLVM:   call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[ARR]], ptr align 4 
@[[FUNC5_ARR:.*]], i64 8, i1 false)
 
 // OGCG: %[[ARR:.*]] = alloca [2 x [1 x i32]], align 4
 // OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[ARR]], ptr align 4 
@[[FUN5_ARR]], i64 8, i1 false)
@@ -328,7 +328,7 @@ void func7() {
 
 // LLVM: define{{.*}} void @_Z5func7v(){{.*}}
 // LLVM:   %[[ARR:.*]] = alloca [1 x ptr], i64 1, align 8
-// LLVM:   call void @llvm.memcpy.p0.p0.i64(ptr %[[ARR]], ptr 
@[[FUNC7_ARR:.*]], i64 8, i1 false)
+// LLVM:   call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[ARR]], ptr align 8 
@[[FUNC7_ARR:.*]], i64 8, i1 false)
 
 // OGCG: %[[ARR:.*]] = alloca [1 x ptr], align 8
 // OGCG: call void @llvm.memset.p0.i64(ptr align 8 %[[ARR]], i8 0, i64 8, i1 
false)
@@ -479,7 +479,7 @@ void array_with_complex_elements() {
 // CIR: cir.copy %[[CONST]] to %[[ARR_ADDR]] : 
!cir.ptr<!cir.array<!cir.complex<!cir.float> x 2>>
 
 // LLVM: %[[ARR_ADDR:.*]] = alloca [2 x { float, float }], i64 1, align 16
-// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[ARR_ADDR]], ptr 
@[[COMPLEX_ARR:.*]], i64 16, i1 false)
+// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[ARR_ADDR]], ptr align 
4 @[[COMPLEX_ARR:.*]], i64 16, i1 false)
 
 // OGCG: %[[ARR_ADDR:.*]] = alloca [2 x { float, float }], align 16
 // OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 16 %[[ARR_ADDR]], ptr 
align 16 @__const._Z27array_with_complex_elementsv.arr, i64 16, i1 false)
diff --git a/clang/test/CIR/CodeGen/atomic-libcall.c 
b/clang/test/CIR/CodeGen/atomic-libcall.c
index 53685dd1b543d..f7f0e89767a9d 100644
--- a/clang/test/CIR/CodeGen/atomic-libcall.c
+++ b/clang/test/CIR/CodeGen/atomic-libcall.c
@@ -67,7 +67,7 @@ void c11_load(_Atomic(struct Big) *ptr) {
   // CIR-NEXT: %[[ORDER:.+]] = cir.const #cir.int<0> : !s32i
   // CIR-NEXT: cir.call @__atomic_load(%[[SIZE]], %[[PTR_VOIDPTR]], 
%[[TEMP_VOIDPTR]], %[[ORDER]]) : (!u64i {llvm.noundef}, !cir.ptr<!void> 
{llvm.noundef}, !cir.ptr<!void> {llvm.noundef}, !s32i {llvm.noundef}) -> ()
   // CIR-NEXT: %[[TEMP_CAST:.+]] = cir.cast bitcast %[[TEMP_INTPTR]] : 
!cir.ptr<!cir.int<u, 192>> -> !cir.ptr<!rec_Big>
-  // CIR-NEXT: cir.copy %[[TEMP_CAST]] to %[[DEST_SLOT]] : !cir.ptr<!rec_Big>
+  // CIR-NEXT: cir.copy %[[TEMP_CAST]] align(4) to %[[DEST_SLOT]] align(4) : 
!cir.ptr<!rec_Big>
 
   // LLVM:      %[[DEST_SLOT:.+]] = alloca %struct.Big
   // LLVM-NEXT: %[[TEMP_SLOT:.+]] = alloca %struct.Big
@@ -123,7 +123,7 @@ void c11_store(_Atomic(struct Big) *dest, struct Big *val) {
   __c11_atomic_store(dest, *val, __ATOMIC_RELAXED);
   // CIR:      %[[DEST_PTR:.+]] = cir.load align(8) %{{.+}} : 
!cir.ptr<!cir.ptr<!rec_Big>>, !cir.ptr<!rec_Big>
   // CIR-NEXT: %[[VALUE_PTR:.+]] = cir.load deref align(8) %{{.+}} : 
!cir.ptr<!cir.ptr<!rec_Big>>, !cir.ptr<!rec_Big>
-  // CIR-NEXT: cir.copy %[[VALUE_PTR]] to %[[TEMP_SLOT:.+]] : 
!cir.ptr<!rec_Big>
+  // CIR-NEXT: cir.copy %[[VALUE_PTR]] align(4) to %[[TEMP_SLOT:.+]] align(4) 
: !cir.ptr<!rec_Big>
   // CIR-NEXT: %[[DEST_INTPTR:.+]] = cir.cast bitcast %[[DEST_PTR]] : 
!cir.ptr<!rec_Big> -> !cir.ptr<!cir.int<u, 192>>
   // CIR-NEXT: %[[VALUE_INTPTR:.+]] = cir.cast bitcast %[[TEMP_SLOT]] : 
!cir.ptr<!rec_Big> -> !cir.ptr<!cir.int<u, 192>>
   // CIR-NEXT: %[[SIZE:.+]] = cir.const #cir.int<24> : !u64i
diff --git a/clang/test/CIR/CodeGen/binassign.c 
b/clang/test/CIR/CodeGen/binassign.c
index b650211646623..13ef5b7db0555 100644
--- a/clang/test/CIR/CodeGen/binassign.c
+++ b/clang/test/CIR/CodeGen/binassign.c
@@ -81,16 +81,16 @@ void binary_assign_struct() {
 // CIR:   %[[LS:.*]] = cir.alloca "ls" {{.*}} : !cir.ptr<![[REC_S:.*]]>
 // CIR:   %[[LSV:.*]] = cir.alloca "lsv" {{.*}} : !cir.ptr<![[REC_SV:.*]]>
 // CIR:   %[[GS_PTR:.*]] = cir.get_global @gs : !cir.ptr<![[REC_S]]>
-// CIR:   cir.copy %[[GS_PTR]] to %[[LS]] : !cir.ptr<![[REC_S]]>
+// CIR:   cir.copy %[[GS_PTR]] align(4) to %[[LS]] align(4) : 
!cir.ptr<![[REC_S]]>
 // CIR:   %[[GSV_PTR:.*]] = cir.get_global @gsv : !cir.ptr<![[REC_SV]]>
-// CIR:   cir.copy %[[GSV_PTR]] to %[[LSV]] volatile : !cir.ptr<![[REC_SV]]>
+// CIR:   cir.copy %[[GSV_PTR]] align(4) to %[[LSV]] align(4) volatile : 
!cir.ptr<![[REC_SV]]>
 // CIR:   cir.return
 
 // LLVM: define {{.*}}void @binary_assign_struct()
 // LLVM:   %[[LS_PTR:.*]] = alloca %struct.S
 // LLVM:   %[[LSV_PTR:.*]] = alloca %struct.SV
-// LLVM:   call void @llvm.memcpy.p0.p0.i64(ptr %[[LS_PTR]], ptr @gs, i64 8, 
i1 false)
-// LLVM:   call void @llvm.memcpy.p0.p0.i64(ptr %[[LSV_PTR]], ptr @gsv, i64 8, 
i1 true)
+// LLVM:   call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[LS_PTR]], ptr align 
4 @gs, i64 8, i1 false)
+// LLVM:   call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[LSV_PTR]], ptr 
align 4 @gsv, i64 8, i1 true)
 // LLVM:   ret void
 
 // OGCG: define {{.*}}void @binary_assign_...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/206341
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to