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