Skip to content

Commit bee102e

Browse files
bruteforceboylanza
authored andcommitted
[CIR][ABI][AArch64][Lowering] support for calling struct types in range (64, 128) (#1141)
This PR adds support for the lowering of AArch64 calls with structs having sizes greater than 64 and less than 128. The idea is from the original [CodeGen](https://github.com/llvm/clangir/blob/da601b374deea6665f710f7e432dfa82f457059e/clang/lib/CodeGen/CGCall.cpp#L1329), where we perform a coercion through memory for these type of calls. I have added a test for this.
1 parent 81285c7 commit bee102e

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerFunction.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,13 @@ mlir::Value createCoercedValue(mlir::Value Src, mlir::Type Ty,
336336
return CGF.buildAggregateBitcast(Src, Ty);
337337
}
338338

339+
if (auto alloca = findAlloca(Src.getDefiningOp())) {
340+
auto tmpAlloca = createTmpAlloca(CGF, alloca.getLoc(), Ty);
341+
createMemCpy(CGF, tmpAlloca, alloca, SrcSize.getFixedValue());
342+
return CGF.getRewriter().create<LoadOp>(alloca.getLoc(),
343+
tmpAlloca.getResult());
344+
}
345+
339346
cir_cconv_unreachable("NYI");
340347
}
341348

clang/test/CIR/CallConvLowering/AArch64/aarch64-cc-structs.c

+25
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,31 @@ GT_128 call_and_get_gt_128() {
206206
// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[#V1]], ptr %[[#V2]], i64 12, i1 false)
207207
void passS(S s) {}
208208

209+
// CHECK: @callS()
210+
// CHECK: %[[#V0:]] = cir.alloca !ty_S, !cir.ptr<!ty_S>, ["s"] {alignment = 4 : i64}
211+
// CHECK: %[[#V1:]] = cir.alloca !cir.array<!u64i x 2>, !cir.ptr<!cir.array<!u64i x 2>>, ["tmp"] {alignment = 8 : i64}
212+
// CHECK: %[[#V2:]] = cir.load %[[#V0]] : !cir.ptr<!ty_S>, !ty_S
213+
// CHECK: %[[#V3:]] = cir.cast(bitcast, %[[#V0]] : !cir.ptr<!ty_S>), !cir.ptr<!void>
214+
// CHECK: %[[#V4:]] = cir.cast(bitcast, %[[#V1]] : !cir.ptr<!cir.array<!u64i x 2>>), !cir.ptr<!void>
215+
// CHECK: %[[#V5:]] = cir.const #cir.int<12> : !u64i
216+
// CHECK: cir.libc.memcpy %[[#V5]] bytes from %[[#V3]] to %[[#V4]] : !u64i, !cir.ptr<!void> -> !cir.ptr<!void>
217+
// CHECK: %[[#V6:]] = cir.load %[[#V1]] : !cir.ptr<!cir.array<!u64i x 2>>, !cir.array<!u64i x 2>
218+
// CHECK: cir.call @passS(%[[#V6]]) : (!cir.array<!u64i x 2>) -> ()
219+
// CHECK: cir.return
220+
221+
// LLVM: @callS()
222+
// LLVM: %[[#V1:]] = alloca %struct.S, i64 1, align 4
223+
// LLVM: %[[#V2:]] = alloca [2 x i64], i64 1, align 8
224+
// LLVM: %[[#V3:]] = load %struct.S, ptr %[[#V1]], align 4
225+
// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[#V2]], ptr %[[#V1]], i64 12, i1 false)
226+
// LLVM: %[[#V4:]] = load [2 x i64], ptr %[[#V2]], align 8
227+
// LLVM: call void @passS([2 x i64] %[[#V4]])
228+
// LLVM: ret void
229+
void callS() {
230+
S s;
231+
passS(s);
232+
}
233+
209234
typedef struct {
210235
uint8_t a;
211236
uint16_t b;

0 commit comments

Comments
 (0)