diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerFunction.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerFunction.cpp index 06242e52383a..c85d95ba2ddd 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerFunction.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerFunction.cpp @@ -336,6 +336,13 @@ mlir::Value createCoercedValue(mlir::Value Src, mlir::Type Ty, return CGF.buildAggregateBitcast(Src, Ty); } + if (auto alloca = findAlloca(Src.getDefiningOp())) { + auto tmpAlloca = createTmpAlloca(CGF, alloca.getLoc(), Ty); + createMemCpy(CGF, tmpAlloca, alloca, SrcSize.getFixedValue()); + return CGF.getRewriter().create(alloca.getLoc(), + tmpAlloca.getResult()); + } + cir_cconv_unreachable("NYI"); } diff --git a/clang/test/CIR/CallConvLowering/AArch64/aarch64-cc-structs.c b/clang/test/CIR/CallConvLowering/AArch64/aarch64-cc-structs.c index 969d40842b75..c9cb857b3a03 100644 --- a/clang/test/CIR/CallConvLowering/AArch64/aarch64-cc-structs.c +++ b/clang/test/CIR/CallConvLowering/AArch64/aarch64-cc-structs.c @@ -206,6 +206,31 @@ GT_128 call_and_get_gt_128() { // LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[#V1]], ptr %[[#V2]], i64 12, i1 false) void passS(S s) {} +// CHECK: @callS() +// CHECK: %[[#V0:]] = cir.alloca !ty_S, !cir.ptr, ["s"] {alignment = 4 : i64} +// CHECK: %[[#V1:]] = cir.alloca !cir.array, !cir.ptr>, ["tmp"] {alignment = 8 : i64} +// CHECK: %[[#V2:]] = cir.load %[[#V0]] : !cir.ptr, !ty_S +// CHECK: %[[#V3:]] = cir.cast(bitcast, %[[#V0]] : !cir.ptr), !cir.ptr +// CHECK: %[[#V4:]] = cir.cast(bitcast, %[[#V1]] : !cir.ptr>), !cir.ptr +// CHECK: %[[#V5:]] = cir.const #cir.int<12> : !u64i +// CHECK: cir.libc.memcpy %[[#V5]] bytes from %[[#V3]] to %[[#V4]] : !u64i, !cir.ptr -> !cir.ptr +// CHECK: %[[#V6:]] = cir.load %[[#V1]] : !cir.ptr>, !cir.array +// CHECK: cir.call @passS(%[[#V6]]) : (!cir.array) -> () +// CHECK: cir.return + +// LLVM: @callS() +// LLVM: %[[#V1:]] = alloca %struct.S, i64 1, align 4 +// LLVM: %[[#V2:]] = alloca [2 x i64], i64 1, align 8 +// LLVM: %[[#V3:]] = load %struct.S, ptr %[[#V1]], align 4 +// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[#V2]], ptr %[[#V1]], i64 12, i1 false) +// LLVM: %[[#V4:]] = load [2 x i64], ptr %[[#V2]], align 8 +// LLVM: call void @passS([2 x i64] %[[#V4]]) +// LLVM: ret void +void callS() { + S s; + passS(s); +} + typedef struct { uint8_t a; uint16_t b;