1 ; RUN: opt < %s -correlated-propagation -S | FileCheck %s 2 3 ; CHECK-LABEL: @simple( 4 define i8 @simple(i1) { 5 entry: 6 %s = select i1 %0, i8 0, i8 1 7 br i1 %0, label %then, label %else 8 9 then: 10 ; CHECK: ret i8 0 11 %a = phi i8 [ %s, %entry ] 12 ret i8 %a 13 14 else: 15 ; CHECK: ret i8 1 16 %b = phi i8 [ %s, %entry ] 17 ret i8 %b 18 } 19 20 ; CHECK-LABEL: @loop( 21 define void @loop(i32) { 22 entry: 23 br label %loop 24 25 loop: 26 %idx = phi i32 [ %0, %entry ], [ %sel, %loop ] 27 ; CHECK: %idx = phi i32 [ %0, %entry ], [ %2, %loop ] 28 %1 = icmp eq i32 %idx, 0 29 %2 = add i32 %idx, -1 30 %sel = select i1 %1, i32 0, i32 %2 31 br i1 %1, label %out, label %loop 32 33 out: 34 ret void 35 } 36 37 ; CHECK-LABEL: @not_correlated( 38 define i8 @not_correlated(i1, i1) { 39 entry: 40 %s = select i1 %0, i8 0, i8 1 41 br i1 %1, label %then, label %else 42 43 then: 44 ; CHECK: ret i8 %s 45 %a = phi i8 [ %s, %entry ] 46 ret i8 %a 47 48 else: 49 ; CHECK: ret i8 %s 50 %b = phi i8 [ %s, %entry ] 51 ret i8 %b 52 } 53 54 @c = global i32 0, align 4 55 @b = global i32 0, align 4 56 57 ; CHECK-LABEL: @PR23752( 58 define i32 @PR23752() { 59 entry: 60 br label %for.body 61 62 for.body: 63 %phi = phi i32 [ 0, %entry ], [ %sel, %for.body ] 64 %sel = select i1 icmp sgt (i32* @b, i32* @c), i32 %phi, i32 1 65 %cmp = icmp ne i32 %sel, 1 66 br i1 %cmp, label %for.body, label %if.end 67 68 ; CHECK: %[[sel:.*]] = select i1 icmp sgt (i32* @b, i32* @c), i32 0, i32 1 69 ; CHECK-NEXT: %[[cmp:.*]] = icmp ne i32 %[[sel]], 1 70 ; CHECK-NEXT: br i1 %[[cmp]] 71 72 if.end: 73 ret i32 %sel 74 ; CHECK: ret i32 1 75 } 76 77 define i1 @test1(i32* %p, i1 %unknown) { 78 ; CHECK-LABEL: @test1 79 %pval = load i32, i32* %p 80 %cmp1 = icmp slt i32 %pval, 255 81 br i1 %cmp1, label %next, label %exit 82 83 next: 84 %min = select i1 %unknown, i32 %pval, i32 5 85 ;; TODO: This pointless branch shouldn't be neccessary 86 br label %next2 87 next2: 88 ; CHECK-LABEL: next2: 89 ; CHECK: ret i1 false 90 %res = icmp eq i32 %min, 255 91 ret i1 %res 92 93 exit: 94 ; CHECK-LABEL: exit: 95 ; CHECK: ret i1 true 96 ret i1 true 97 } 98 99 ; Check that we take a conservative meet 100 define i1 @test2(i32* %p, i32 %qval, i1 %unknown) { 101 ; CHECK-LABEL: test2 102 %pval = load i32, i32* %p 103 %cmp1 = icmp slt i32 %pval, 255 104 br i1 %cmp1, label %next, label %exit 105 106 next: 107 %min = select i1 %unknown, i32 %pval, i32 %qval 108 ;; TODO: This pointless branch shouldn't be neccessary 109 br label %next2 110 next2: 111 ; CHECK-LABEL: next2 112 ; CHECK: ret i1 %res 113 %res = icmp eq i32 %min, 255 114 ret i1 %res 115 116 exit: 117 ; CHECK-LABEL: exit: 118 ; CHECK: ret i1 true 119 ret i1 true 120 } 121 122 ; Same as @test2, but for the opposite select input 123 define i1 @test3(i32* %p, i32 %qval, i1 %unknown) { 124 ; CHECK-LABEL: test3 125 %pval = load i32, i32* %p 126 %cmp1 = icmp slt i32 %pval, 255 127 br i1 %cmp1, label %next, label %exit 128 129 next: 130 %min = select i1 %unknown, i32 %qval, i32 %pval 131 ;; TODO: This pointless branch shouldn't be neccessary 132 br label %next2 133 next2: 134 ; CHECK-LABEL: next2 135 ; CHECK: ret i1 %res 136 %res = icmp eq i32 %min, 255 137 ret i1 %res 138 139 exit: 140 ; CHECK-LABEL: exit: 141 ; CHECK: ret i1 true 142 ret i1 true 143 } 144 145 ; Conflicting constants (i.e. isOverdefined result) 146 ; NOTE: Using doubles in this version is a bit of a hack. This 147 ; is to get around the fact that all integers (including constants 148 ; and non-constants) are actually represented as constant-ranges. 149 define i1 @test4(i32* %p, i32 %qval, i1 %unknown) { 150 ; CHECK-LABEL: test4 151 %pval = load i32, i32* %p 152 %cmp1 = icmp slt i32 %pval, 255 153 br i1 %cmp1, label %next, label %exit 154 155 next: 156 %min = select i1 %unknown, double 1.0, double 0.0 157 ;; TODO: This pointless branch shouldn't be neccessary 158 br label %next2 159 next2: 160 ; CHECK-LABEL: next2 161 ; CHECK: ret i1 %res 162 %res = fcmp oeq double %min, 300.0 163 ret i1 %res 164 165 exit: 166 ; CHECK-LABEL: exit: 167 ; CHECK: ret i1 true 168 ret i1 true 169 } 170 171 ;; Using the condition to clamp the result 172 ;; 173 174 define i1 @test5(i32* %p, i1 %unknown) { 175 ; CHECK-LABEL: @test5 176 %pval = load i32, i32* %p 177 %cmp1 = icmp slt i32 %pval, 255 178 br i1 %cmp1, label %next, label %exit 179 180 next: 181 %cond = icmp sgt i32 %pval, 0 182 %min = select i1 %cond, i32 %pval, i32 5 183 ;; TODO: This pointless branch shouldn't be neccessary 184 br label %next2 185 next2: 186 ; CHECK-LABEL: next2: 187 ; CHECK: ret i1 false 188 %res = icmp eq i32 %min, -1 189 ret i1 %res 190 191 exit: 192 ; CHECK-LABEL: exit: 193 ; CHECK: ret i1 true 194 ret i1 true 195 } 196 197 define i1 @test6(i32* %p, i1 %unknown) { 198 ; CHECK-LABEL: @test6 199 %pval = load i32, i32* %p 200 %cmp1 = icmp ult i32 %pval, 255 201 br i1 %cmp1, label %next, label %exit 202 203 next: 204 %cond = icmp ne i32 %pval, 254 205 %sel = select i1 %cond, i32 %pval, i32 1 206 ;; TODO: This pointless branch shouldn't be neccessary 207 br label %next2 208 next2: 209 ; CHECK-LABEL: next2: 210 ; CHECK: ret i1 true 211 %res = icmp slt i32 %sel, 254 212 ret i1 %res 213 214 exit: 215 ; CHECK-LABEL: exit: 216 ; CHECK: ret i1 true 217 ret i1 true 218 } 219