| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt -passes=instcombine -S < %s | FileCheck %s |
| |
| ; Check that InstCombine can sink instructions to the landingpad of the invoke. |
| |
| define void @t0_noop(i32 %arg) personality ptr @__gxx_personality_v0 { |
| ; CHECK-LABEL: @t0_noop( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[C:%.*]] = call i1 @cond() |
| ; CHECK-NEXT: br i1 [[C]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] |
| ; CHECK: if.then: |
| ; CHECK-NEXT: invoke void @simple_throw() |
| ; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] |
| ; CHECK: invoke.cont: |
| ; CHECK-NEXT: unreachable |
| ; CHECK: lpad: |
| ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 } |
| ; CHECK-NEXT: cleanup |
| ; CHECK-NEXT: [[V0:%.*]] = add i32 [[ARG:%.*]], 42 |
| ; CHECK-NEXT: call void @consume(i32 [[V0]]) |
| ; CHECK-NEXT: call void @destructor() |
| ; CHECK-NEXT: resume { ptr, i32 } [[EH]] |
| ; CHECK: if.end: |
| ; CHECK-NEXT: [[V1:%.*]] = add i32 [[ARG]], 24 |
| ; CHECK-NEXT: call void @consume(i32 [[V1]]) |
| ; CHECK-NEXT: call void @sideeffect() |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| %c = call i1 @cond() |
| %v0 = add i32 %arg, 42 |
| %v1 = add i32 %arg, 24 |
| br i1 %c, label %if.then, label %if.end |
| |
| if.then: |
| invoke void @simple_throw() to label %invoke.cont unwind label %lpad |
| |
| invoke.cont: |
| unreachable |
| |
| lpad: |
| %eh = landingpad { ptr, i32 } cleanup |
| call void @consume(i32 %v0) |
| call void @destructor() |
| resume { ptr, i32 } %eh |
| |
| if.end: |
| call void @consume(i32 %v1) |
| call void @sideeffect() |
| ret void |
| } |
| |
| declare i1 @cond() |
| |
| declare void @sideeffect() |
| |
| declare void @simple_throw() noreturn |
| |
| declare void @destructor() |
| |
| declare void @consume(i32) |
| |
| declare dso_local i32 @__gxx_personality_v0(...) |