@@ -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