Skip to content

Commit d3ee486

Browse files
authored
[CIR][Lowering] Enabled VAArg lowering for cir::PointerType (#1762)
`cir::PointerType` was not included in the applicability guard for `cir::VAArg` lowering during `LoweringPrepare`. Since we don't have generic LLVM `cir::VAArgOp` (see [more info](#1088 (comment))) this causes an NYI error during lowering that doesn't need to happen. To fix this I added the missing `cir::PointerType` to the `isa`. There is probably a more comprehensive fix to this if someone is interested, this check should be removed and let the (possible) error occur at the actual NYI site.
1 parent a42534e commit d3ee486

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/LoweringPrepareX86CXXABI.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ mlir::Value LoweringPrepareX86CXXABI::lowerVAArgX86_64(
9191
// Let's hope LLVM's va_arg instruction can take care of it.
9292
// Remove this when X86_64ABIInfo::classify can take care of every type.
9393
if (!mlir::isa<VoidType, IntType, SingleType, DoubleType, BoolType,
94-
cir::RecordType, LongDoubleType>(op.getType()))
94+
cir::RecordType, LongDoubleType, cir::PointerType>(
95+
op.getType()))
9596
return nullptr;
9697

9798
// Assume that va_list type is correct; should be pointer to LLVM type:

clang/test/CIR/Lowering/var-arg-x86_64.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,63 @@ long double f2(int n, ...) {
125125
// CIR: [[CAST_ALIGNED_VALUE:%.+]] = cir.load [[CAST_ALIGNED]]
126126
// CIR: cir.store{{.*}} [[CAST_ALIGNED_VALUE]], [[RES]]
127127
// CIR. cir.via.end
128+
129+
const char *f3(va_list args) {
130+
return va_arg(args, const char *);
131+
}
132+
133+
// CHECK: define{{.*}} @f3
134+
// CHECK: [[VA_LIST_ALLOCA:%.+]] = alloca ptr
135+
// ...
136+
// CHECK: [[VA_LIST:%.+]] = load {{.*}} [[VA_LIST_ALLOCA]]
137+
// CHECK: [[OFFSET_PTR:%.+]] = getelementptr {{.*}} [[VA_LIST]], i32 0, i32 0
138+
// CHECK: [[OFFSET:%.+]] = load {{.*}}, ptr [[OFFSET_PTR]]
139+
// CHECK: [[CMP:%.+]] = icmp ule i32 [[OFFSET]], 40
140+
// CHECK: br i1 [[CMP]], label %[[THEN_BB:.+]], label %[[ELSE_BB:.+]]
141+
//
142+
// CHECK: [[THEN_BB]]:
143+
// ...
144+
// CHECK: [[NEW_OFFSET:%.+]] = add i32 [[OFFSET]], 8
145+
// CHECK: store i32 [[NEW_OFFSET]], ptr [[OFFSET_PTR]]
146+
// CHECK: br label %[[CONT_BB:.+]]
147+
//
148+
// CHECK: [[ELSE_BB]]:
149+
// ...
150+
// CHECK: [[OVERFLOW_ARG_AREA_ADDR:%.+]] = getelementptr {{.*}} [[VA_LIST]], i32 0, i32 2
151+
// CHECK: [[OVERFLOW_ARG_AREA:%.+]] = load ptr, ptr [[OVERFLOW_ARG_AREA_ADDR]]
152+
// CHECK: [[OVERFLOW_ARG_AREA_OFFSET:%.+]] = getelementptr {{.*}} [[OVERFLOW_ARG_AREA]], i64 8
153+
// CHECK: store ptr [[OVERFLOW_ARG_AREA_OFFSET]], ptr [[OVERFLOW_ARG_AREA_ADDR]]
154+
// CHECK: br label %[[CONT_BB]]
155+
//
156+
// CHECK: [[CONT_BB]]:
157+
// ...
158+
// CHECK: ret
159+
160+
// CIR-LABEL: cir.func dso_local @f3(
161+
// CIR: %[[VALIST_VAR:.*]] = cir.alloca !cir.ptr<!rec___va_list_tag>, !cir.ptr<!cir.ptr<!rec___va_list_tag>>, ["args", init] {alignment = 8 : i64}
162+
// CIR: %[[VALIST:.*]] = cir.load align(8) %[[VALIST_VAR]] : !cir.ptr<!cir.ptr<!rec___va_list_tag>>, !cir.ptr<!rec___va_list_tag>
163+
// CIR: %[[GP_OFFSET_PTR:.*]] = cir.get_member %[[VALIST]][0] {name = "gp_offset"} : !cir.ptr<!rec___va_list_tag> -> !cir.ptr<!u32i>
164+
// CIR: %[[GP_OFFSET:.*]] = cir.load %[[GP_OFFSET_PTR]] : !cir.ptr<!u32i>, !u32i
165+
// CIR: %[[VAL_6:.*]] = cir.const #cir.int<40> : !u32i
166+
// CIR: %[[VAL_7:.*]] = cir.cmp(le, %[[GP_OFFSET]], %[[VAL_6]]) : !u32i, !cir.bool
167+
// CIR: cir.brcond %[[VAL_7]]
168+
169+
// CIR: %[[REG_SAVE_AREA_PTR:.*]] = cir.get_member %[[VALIST]][3] {name = "reg_save_area"} : !cir.ptr<!rec___va_list_tag> -> !cir.ptr<!cir.ptr<!void>>
170+
// CIR: %[[REG_SAVE_AREA:.*]] = cir.load %[[REG_SAVE_AREA_PTR]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
171+
// CIR: %[[CUR_REG_SAVE_AREA:.*]] = cir.ptr_stride(%[[REG_SAVE_AREA]] : !cir.ptr<!void>, %[[GP_OFFSET]] : !u32i), !cir.ptr<!void>
172+
// CIR: %[[VAL_11:.*]] = cir.const #cir.int<8> : !u32i
173+
// CIR: %[[NEW_REG_SAVE_AREA:.*]] = cir.binop(add, %[[GP_OFFSET]], %[[VAL_11]]) : !u32i
174+
// CIR: cir.store %[[NEW_REG_SAVE_AREA]], %[[GP_OFFSET_PTR]] : !u32i, !cir.ptr<!u32i>
175+
// CIR: cir.br ^[[CONT_BB:.*]](%[[CUR_REG_SAVE_AREA]] : !cir.ptr<!void>)
176+
177+
// CIR: %[[OVERFLOW_ARG_AREA_PTR:.*]] = cir.get_member %[[VALIST]][2] {name = "overflow_arg_area"} : !cir.ptr<!rec___va_list_tag> -> !cir.ptr<!cir.ptr<!void>>
178+
// CIR: %[[OVERFLOW_ARG_AREA:.*]] = cir.load %[[OVERFLOW_ARG_AREA_PTR]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
179+
// CIR: %[[VAL_15:.*]] = cir.const #cir.int<8> : !s32i
180+
// CIR: %[[CUR_OVERFLOW_ARG_AREA:.*]] = cir.cast(bitcast, %[[OVERFLOW_ARG_AREA]] : !cir.ptr<!void>), !cir.ptr<!s8i>
181+
// CIR: %[[NEW_OVERFLOW_ARG_AREA:.*]] = cir.ptr_stride(%[[CUR_OVERFLOW_ARG_AREA]] : !cir.ptr<!s8i>, %[[VAL_15]] : !s32i), !cir.ptr<!s8i>
182+
// CIR: %[[VAL_18:.*]] = cir.cast(bitcast, %[[OVERFLOW_ARG_AREA_PTR]] : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!cir.ptr<!s8i>>
183+
// CIR: cir.store %[[NEW_OVERFLOW_ARG_AREA]], %[[VAL_18]] : !cir.ptr<!s8i>, !cir.ptr<!cir.ptr<!s8i>>
184+
// CIR: cir.br ^[[CONT_BB]](%[[OVERFLOW_ARG_AREA]] : !cir.ptr<!void>)
185+
186+
// ...
187+
// CIR: cir.return

0 commit comments

Comments
 (0)