llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang 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
