@@ -16,6 +16,8 @@ double d(int a, int b) {
1616// CIR-NEXT: cir.store{{.*}} %[[STR_ADD]], %[[ADDR]] : !cir.ptr<!s8i>, !cir.ptr<!cir.ptr<!s8i>>
1717// CIR-NEXT: cir.throw %[[ADDR]] : !cir.ptr<!cir.ptr<!s8i>>, @_ZTIPKc
1818// CIR-NEXT: cir.unreachable
19+ // CIR-NEXT: ^bb1: // no predecessors
20+ // CIR-NEXT: cir.yield
1921// CIR-NEXT: }
2022
2123// LLVM: %[[ADDR:.*]] = call ptr @__cxa_allocate_exception(i64 8)
@@ -293,3 +295,140 @@ void refoo4() {
293295// LLVM: invoke void @__cxa_rethrow
294296// LLVM: unreachable
295297// LLVM: invoke void @_ZN1SC2Ev
298+
299+ void statements () {
300+ throw 0 ;
301+ 123 + 456 ;
302+ }
303+
304+ // CIR: cir.func @_Z10statementsv()
305+ // CIR-NEXT: %[[V0:.*]] = cir.alloc.exception 4 -> !cir.ptr<!s32i>
306+ // CIR-NEXT: %[[V1:.*]] = cir.const #cir.int<0> : !s32i
307+ // CIR-NEXT: cir.store align(16) %[[V1]], %[[V0]] : !s32i, !cir.ptr<!s32i>
308+ // CIR-NEXT: cir.throw %[[V0]] : !cir.ptr<!s32i>, @_ZTIi
309+ // CIR-NEXT: cir.unreachable
310+ // CIR-NEXT: ^bb1:
311+ // CIR-NEXT: %[[V2:.*]] = cir.const #cir.int<123> : !s32i
312+ // CIR-NEXT: %[[V3:.*]] = cir.const #cir.int<456> : !s32i
313+ // CIR-NEXT: %[[V4:.*]] = cir.binop(add, %[[V2]], %[[V3]]) nsw : !s32i
314+ // CIR-NEXT: cir.return
315+ // CIR-NEXT: }
316+
317+ // LLVM: call void @__cxa_throw
318+ // LLVM: unreachable
319+
320+ void paren_expr () { (throw 0 , 123 + 456 ); }
321+
322+ // CIR: cir.func @_Z10paren_exprv()
323+ // CIR-NEXT: %[[V0:.*]] = cir.alloc.exception 4 -> !cir.ptr<!s32i>
324+ // CIR-NEXT: %[[V1:.*]] = cir.const #cir.int<0> : !s32i
325+ // CIR-NEXT: cir.store align(16) %[[V1]], %[[V0]] : !s32i, !cir.ptr<!s32i>
326+ // CIR-NEXT: cir.throw %[[V0]] : !cir.ptr<!s32i>, @_ZTIi
327+ // CIR-NEXT: cir.unreachable
328+ // CIR-NEXT: ^bb1:
329+ // CIR-NEXT: %[[V2:.*]] = cir.const #cir.int<123> : !s32i
330+ // CIR-NEXT: %[[V3:.*]] = cir.const #cir.int<456> : !s32i
331+ // CIR-NEXT: %[[V4:.*]] = cir.binop(add, %[[V2]], %[[V3]]) nsw : !s32i
332+ // CIR-NEXT: cir.return
333+ // CIR-NEXT: }
334+
335+ // LLVM: call void @__cxa_throw
336+ // LLVM: unreachable
337+
338+ int ternary_throw1 (bool condition, int x) {
339+ return condition ? throw x : x;
340+ }
341+
342+ // CIR: cir.func @_Z14ternary_throw1bi(%arg0: !cir.bool
343+ // CIR-NEXT: %[[V0:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["condition", init] {alignment = 1 : i64}
344+ // CIR-NEXT: %[[V1:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init] {alignment = 4 : i64}
345+ // CIR-NEXT: %[[V2:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] {alignment = 4 : i64}
346+ // CIR-NEXT: %[[V3:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["cleanup.cond"] {alignment = 1 : i64}
347+ // CIR-NEXT: %[[V4:.*]] = cir.const #false
348+ // CIR-NEXT: %[[V5:.*]] = cir.const #true
349+ // CIR-NEXT: cir.store %arg0, %[[V0]] : !cir.bool, !cir.ptr<!cir.bool>
350+ // CIR-NEXT: cir.store %arg1, %[[V1]] : !s32i, !cir.ptr<!s32i>
351+ // CIR-NEXT: %[[V6:.*]] = cir.load align(1) %[[V0]] : !cir.ptr<!cir.bool>, !cir.bool
352+ // CIR-NEXT: cir.store align(1) %[[V4]], %[[V3]] : !cir.bool, !cir.ptr<!cir.bool>
353+ // CIR-NEXT: %[[V7:.*]] = cir.ternary(%[[V6]], true {
354+ // CIR-NEXT: %[[V9:.*]] = cir.alloc.exception 4 -> !cir.ptr<!s32i>
355+ // CIR-NEXT: cir.store align(1) %[[V5]], %[[V3]] : !cir.bool, !cir.ptr<!cir.bool>
356+ // CIR-NEXT: %[[V10:.*]] = cir.load align(4) %[[V1]] : !cir.ptr<!s32i>, !s32i
357+ // CIR-NEXT: cir.store align(16) %[[V10]], %[[V9]] : !s32i, !cir.ptr<!s32i>
358+ // CIR-NEXT: cir.throw %[[V9]] : !cir.ptr<!s32i>, @_ZTIi
359+ // CIR-NEXT: cir.unreachable
360+ // CIR-NEXT: ^bb1: // no predecessors
361+ // CIR-NEXT: %[[V11:.*]] = cir.const #cir.int<0> : !s32i loc(#loc173)
362+ // CIR-NEXT: cir.yield %[[V11]] : !s32i
363+ // CIR-NEXT: }, false {
364+ // CIR-NEXT: %[[V9:.*]] = cir.load align(4) %[[V1]] : !cir.ptr<!s32i>, !s32i
365+ // CIR-NEXT: cir.yield %[[V9]] : !s32i
366+ // CIR-NEXT: }) : (!cir.bool) -> !s32i
367+ // CIR-NEXT: cir.store %[[V7]], %[[V2]] : !s32i, !cir.ptr<!s32i>
368+ // CIR-NEXT: %[[V8:.*]] = cir.load %[[V2]] : !cir.ptr<!s32i>, !s32i
369+ // CIR-NEXT: cir.return %[[V8]] : !s32i
370+ // CIR-NEXT: }
371+
372+ // LLVM: @_Z14ternary_throw1bi
373+ // LLVM: %[[V3:.*]] = alloca i8, i64 1, align 1
374+ // LLVM: %[[V4:.*]] = alloca i32, i64 1, align 4
375+ // LLVM: %[[V5:.*]] = alloca i32, i64 1, align 4
376+ // LLVM: %[[V6:.*]] = alloca i8, i64 1, align 1
377+ // LLVM: %[[V7:.*]] = zext i1 %[[V0:.*]] to i8
378+ // LLVM: store i8 %[[V7]], ptr %[[V3]], align 1
379+ // LLVM: store i32 %[[V1:.*]], ptr %[[V4]], align 4
380+ // LLVM: %[[V8:.*]] = load i8, ptr %[[V3]], align 1
381+ // LLVM: %[[V9:.*]] = trunc i8 %[[V8]] to i1
382+ // LLVM: store i8 0, ptr %[[V6]], align 1
383+ // LLVM: br i1 %[[V9]], label %[[B10:.*]], label %[[B14:.*]]
384+ // LLVM: [[B10]]:
385+ // LLVM: %[[V11:.*]] = call ptr @__cxa_allocate_exception(i64 4)
386+ // LLVM: store i8 1, ptr %[[V6]], align 1
387+ // LLVM: %[[V12:.*]] = load i32, ptr %[[V4]], align 4
388+ // LLVM: store i32 %[[V12]], ptr %[[V11]], align 16
389+ // LLVM: call void @__cxa_throw(ptr %[[V11]], ptr @_ZTIi, ptr null)
390+ // LLVM: unreachable
391+ // LLVM: [[B13]]:
392+ // LLVM: br label %[[B16:.*]]
393+ // LLVM: [[B14]]:
394+ // LLVM: %[[V15:.*]] = load i32, ptr %[[V4]], align 4
395+ // LLVM: br label %[[B16]]
396+ // LLVM: [[B16]]:
397+ // LLVM: %[[V17:.*]] = phi i32 [ 0, %[[V13]] ], [ %[[V15]], %[[V14]] ]
398+ // LLVM: store i32 %[[V17]], ptr %[[V5]], align 4
399+ // LLVM: %[[V18:.*]] = load i32, ptr %[[V5]], align 4
400+ // LLVM: ret i32 %[[V18]]
401+
402+ int ternary_throw2 (bool condition, int x) {
403+ return condition ? x : throw x;
404+ }
405+
406+ // LLVM: @_Z14ternary_throw2bi
407+ // LLVM: %[[V3:.*]] = alloca i8, i64 1, align 1
408+ // LLVM: %[[V4:.*]] = alloca i32, i64 1, align 4
409+ // LLVM: %[[V5:.*]] = alloca i32, i64 1, align 4
410+ // LLVM: %[[V6:.*]] = alloca i8, i64 1, align 1
411+ // LLVM: %[[V7:.*]] = zext i1 %[[V0:.*]] to i8
412+ // LLVM: store i8 %[[V7]], ptr %[[V3]], align 1
413+ // LLVM: store i32 %[[V1]], ptr %[[V4]], align 4
414+ // LLVM: %[[V8:.*]] = load i8, ptr %[[V3]], align 1
415+ // LLVM: %[[V9:.*]] = trunc i8 %[[V8]] to i1
416+ // LLVM: store i8 0, ptr %[[V6]], align 1
417+ // LLVM: br i1 %[[V9]], label %[[B10:.*]], label %[[B12:.*]]
418+ // LLVM: [[B10]]:
419+ // LLVM: %[[V11:.*]] = load i32, ptr %[[V4]], align 4
420+ // LLVM: br label %[[B16:.*]]
421+ // LLVM: [[B12]]:
422+ // LLVM: %[[V13:.*]] = call ptr @__cxa_allocate_exception(i64 4)
423+ // LLVM: store i8 1, ptr %[[V6]], align 1
424+ // LLVM: %[[V14:.*]] = load i32, ptr %[[V4]], align 4
425+ // LLVM: store i32 %[[V14]], ptr %[[V13]], align 16
426+ // LLVM: call void @__cxa_throw(ptr %[[V13]], ptr @_ZTIi, ptr null)
427+ // LLVM: unreachable
428+ // LLVM: [[B15:.*]]:
429+ // LLVM: br label %[[B16:.*]]
430+ // LLVM: [[B16]]:
431+ // LLVM: %[[V17:.*]] = phi i32 [ 0, %[[V15]] ], [ %[[V11]], %[[V10]] ]
432+ // LLVM: store i32 %[[V17]], ptr %[[V5]], align 4
433+ // LLVM: %[[V18:.*]] = load i32, ptr %[[V5]], align 4
434+ // LLVM: ret i32 %[[V18]]
0 commit comments