1; RUN: opt < %s -gvn -enable-pre -S | FileCheck %s 2; RUN: opt < %s -passes="gvn<pre>" -enable-pre=false -S | FileCheck %s 3 4declare void @may_exit() nounwind 5 6declare void @may_exit_1(i32) nounwind 7 8define i32 @main(i32 %p, i32 %q) { 9 10; CHECK-LABEL: @main( 11 12block1: 13 %cmp = icmp eq i32 %p, %q 14 br i1 %cmp, label %block2, label %block3 15 16block2: 17 %a = add i32 %p, 1 18 br label %block4 19 20block3: 21 br label %block4 22; CHECK: %.pre = add i32 %p, 1 23; CHECK-NEXT: br label %block4 24 25block4: 26 %b = add i32 %p, 1 27 ret i32 %b 28; CHECK: %b.pre-phi = phi i32 [ %.pre, %block3 ], [ %a, %block2 ] 29; CHECK-NEXT: ret i32 %b.pre-phi 30} 31 32; Don't PRE across implicit control flow. 33define i32 @test2(i32 %p, i32 %q) { 34 35; CHECK-LABEL: @test2 36; CHECK: block1: 37 38block1: 39 %cmp = icmp eq i32 %p, %q 40 br i1 %cmp, label %block2, label %block3 41 42block2: 43 %a = sdiv i32 %p, %q 44 br label %block4 45 46block3: 47 br label %block4 48 49; CHECK: block4: 50; CHECK-NEXT: call void @may_exit( 51; CHECK-NEXT: %b = sdiv 52; CHECK-NEXT: ret i32 %b 53 54block4: 55 call void @may_exit() nounwind 56 %b = sdiv i32 %p, %q 57 ret i32 %b 58} 59 60; Don't PRE across implicit control flow. 61define i32 @test3(i32 %p, i32 %q, i1 %r) { 62 63; CHECK-LABEL: @test3 64; CHECK: block1: 65 66block1: 67 br i1 %r, label %block2, label %block3 68 69block2: 70 %a = sdiv i32 %p, %q 71 br label %block4 72 73block3: 74 br label %block4 75 76block4: 77 78; CHECK: block4: 79; CHECK-NEXT: phi i32 80; CHECK-NEXT: call void @may_exit_1( 81; CHECK-NEXT: %b = sdiv 82; CHECK-NEXT: ret i32 %b 83 84 %phi = phi i32 [ 0, %block3 ], [ %a, %block2 ] 85 call void @may_exit_1(i32 %phi) nounwind 86 %b = sdiv i32 %p, %q 87 ret i32 %b 88 89} 90 91; It's OK to PRE an instruction that is guaranteed to be safe to execute 92; speculatively. 93; TODO: Does it make any sense in this case? 94define i32 @test4(i32 %p, i32 %q) { 95 96; CHECK-LABEL: @test4 97; CHECK: block1: 98 99block1: 100 %cmp = icmp eq i32 %p, %q 101 br i1 %cmp, label %block2, label %block3 102 103block2: 104 %a = sdiv i32 %p, 6 105 br label %block4 106 107block3: 108 br label %block4 109 110; CHECK: block4: 111; CHECK-NEXT: %b.pre-phi = phi i32 112; CHECK-NEXT: call void @may_exit( 113; CHECK-NEXT: ret i32 %b 114 115block4: 116 call void @may_exit() nounwind 117 %b = sdiv i32 %p, 6 118 ret i32 %b 119} 120 121; It is OK to PRE across implicit control flow if we don't insert new 122; instructions. 123define i32 @test5(i1 %cond, i32 %p, i32 %q) { 124 125; CHECK-LABEL: @test5 126; CHECK: block1: 127 128block1: 129 br i1 %cond, label %block2, label %block3 130 131block2: 132 %a = sdiv i32 %p, %q 133 br label %block4 134 135block3: 136 %b = sdiv i32 %p, %q 137 br label %block4 138 139; CHECK: block4: 140; CHECK-NEXT: %c.pre-phi = phi i32 [ %b, %block3 ], [ %a, %block2 ] 141; CHECK-NEXT: call void @may_exit() 142; CHECK-NEXT: ret i32 %c.pre-phi 143 144block4: 145 call void @may_exit() nounwind 146 %c = sdiv i32 %p, %q 147 ret i32 %c 148} 149