1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s 3 4; Test basic folding to a conditional branch. 5define i32 @foo(i64 %x, i64 %y) nounwind { 6; CHECK-LABEL: @foo( 7; CHECK-NEXT: entry: 8; CHECK-NEXT: [[EQ:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]] 9; CHECK-NEXT: br i1 [[EQ]], label [[B:%.*]], label [[SWITCH:%.*]] 10; CHECK: switch: 11; CHECK-NEXT: [[LT:%.*]] = icmp slt i64 [[X]], [[Y]] 12; CHECK-NEXT: br i1 [[LT]], label [[A:%.*]], label [[B]] 13; CHECK: common.ret: 14; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ 1, [[A]] ], [ [[RETVAL:%.*]], [[B]] ] 15; CHECK-NEXT: ret i32 [[COMMON_RET_OP]] 16; CHECK: a: 17; CHECK-NEXT: tail call void @bees.a() #[[ATTR0:[0-9]+]] 18; CHECK-NEXT: br label [[COMMON_RET:%.*]] 19; CHECK: b: 20; CHECK-NEXT: [[RETVAL]] = phi i32 [ 0, [[SWITCH]] ], [ 2, [[ENTRY:%.*]] ] 21; CHECK-NEXT: tail call void @bees.b() #[[ATTR0]] 22; CHECK-NEXT: br label [[COMMON_RET]] 23; 24entry: 25 %eq = icmp eq i64 %x, %y 26 br i1 %eq, label %b, label %switch 27switch: 28 %lt = icmp slt i64 %x, %y 29 %qux = select i1 %lt, i32 0, i32 2 30 switch i32 %qux, label %bees [ 31 i32 0, label %a 32 i32 1, label %b 33 i32 2, label %b 34 ] 35a: 36 tail call void @bees.a() nounwind 37 ret i32 1 38b: 39 %retval = phi i32 [0, %switch], [0, %switch], [2, %entry] 40 tail call void @bees.b() nounwind 41 ret i32 %retval 42bees: 43 tail call void @llvm.trap() nounwind 44 unreachable 45} 46 47; Test basic folding to an unconditional branch. 48define i32 @bar(i64 %x, i64 %y) nounwind { 49; CHECK-LABEL: @bar( 50; CHECK-NEXT: entry: 51; CHECK-NEXT: tail call void @bees.a() #[[ATTR0]] 52; CHECK-NEXT: ret i32 0 53; 54entry: 55 %lt = icmp slt i64 %x, %y 56 %qux = select i1 %lt, i32 0, i32 2 57 switch i32 %qux, label %bees [ 58 i32 0, label %a 59 i32 1, label %b 60 i32 2, label %a 61 ] 62a: 63 %retval = phi i32 [0, %entry], [0, %entry], [1, %b] 64 tail call void @bees.a() nounwind 65 ret i32 0 66b: 67 tail call void @bees.b() nounwind 68 br label %a 69bees: 70 tail call void @llvm.trap() nounwind 71 unreachable 72} 73 74; Test the edge case where both values from the select are the default case. 75define void @bazz(i64 %x, i64 %y) nounwind { 76; CHECK-LABEL: @bazz( 77; CHECK-NEXT: entry: 78; CHECK-NEXT: tail call void @bees.b() #[[ATTR0]] 79; CHECK-NEXT: ret void 80; 81entry: 82 %lt = icmp slt i64 %x, %y 83 %qux = select i1 %lt, i32 10, i32 12 84 switch i32 %qux, label %b [ 85 i32 0, label %a 86 i32 1, label %bees 87 i32 2, label %bees 88 ] 89a: 90 tail call void @bees.a() nounwind 91 ret void 92b: 93 tail call void @bees.b() nounwind 94 ret void 95bees: 96 tail call void @llvm.trap() 97 unreachable 98} 99 100; Test the edge case where both values from the select are equal. 101define void @quux(i64 %x, i64 %y) nounwind { 102; CHECK-LABEL: @quux( 103; CHECK-NEXT: entry: 104; CHECK-NEXT: tail call void @bees.a() #[[ATTR0]] 105; CHECK-NEXT: ret void 106; 107entry: 108 %lt = icmp slt i64 %x, %y 109 %qux = select i1 %lt, i32 0, i32 0 110 switch i32 %qux, label %b [ 111 i32 0, label %a 112 i32 1, label %bees 113 i32 2, label %bees 114 ] 115a: 116 tail call void @bees.a() nounwind 117 ret void 118b: 119 tail call void @bees.b() nounwind 120 ret void 121bees: 122 tail call void @llvm.trap() 123 unreachable 124} 125 126; A final test, for phi node munging. 127define i32 @xyzzy(i64 %x, i64 %y) { 128; CHECK-LABEL: @xyzzy( 129; CHECK-NEXT: entry: 130; CHECK-NEXT: [[EQ:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]] 131; CHECK-NEXT: [[LT:%.*]] = icmp slt i64 [[X]], [[Y]] 132; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[LT]], i32 -1, i32 1 133; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = select i1 [[EQ]], i32 0, i32 [[SPEC_SELECT]] 134; CHECK-NEXT: ret i32 [[COMMON_RET_OP]] 135; 136entry: 137 %eq = icmp eq i64 %x, %y 138 br i1 %eq, label %r, label %cont 139cont: 140 %lt = icmp slt i64 %x, %y 141 %qux = select i1 %lt, i32 0, i32 2 142 switch i32 %qux, label %bees [ 143 i32 0, label %a 144 i32 1, label %r 145 i32 2, label %r 146 ] 147r: 148 %val = phi i32 [0, %entry], [1, %cont], [1, %cont] 149 ret i32 %val 150a: 151 ret i32 -1 152bees: 153 tail call void @llvm.trap() 154 unreachable 155} 156 157declare void @llvm.trap() nounwind noreturn 158declare void @bees.a() nounwind 159declare void @bees.b() nounwind 160 161; CHECK: attributes #1 = { cold noreturn nounwind memory(inaccessiblemem: write) } 162