1 ; RUN: llc < %s -march=x86 -mcpu=pentiumpro -verify-machineinstrs | FileCheck %s 2 3 define i32 @func_f(i32 %X) { 4 entry: 5 ; CHECK-LABEL: func_f: 6 ; CHECK: jns 7 %tmp1 = add i32 %X, 1 ; <i32> [#uses=1] 8 %tmp = icmp slt i32 %tmp1, 0 ; <i1> [#uses=1] 9 br i1 %tmp, label %cond_true, label %cond_next 10 11 cond_true: ; preds = %entry 12 %tmp2 = tail call i32 (...) @bar( ) ; <i32> [#uses=0] 13 br label %cond_next 14 15 cond_next: ; preds = %cond_true, %entry 16 %tmp3 = tail call i32 (...) @baz( ) ; <i32> [#uses=0] 17 ret i32 undef 18 } 19 20 declare i32 @bar(...) 21 22 declare i32 @baz(...) 23 24 ; rdar://10633221 25 ; rdar://11355268 26 define i32 @func_g(i32 %a, i32 %b) nounwind { 27 entry: 28 ; CHECK-LABEL: func_g: 29 ; CHECK-NOT: test 30 ; CHECK: cmovs 31 %sub = sub nsw i32 %a, %b 32 %cmp = icmp sgt i32 %sub, 0 33 %cond = select i1 %cmp, i32 %sub, i32 0 34 ret i32 %cond 35 } 36 37 ; rdar://10734411 38 define i32 @func_h(i32 %a, i32 %b) nounwind { 39 entry: 40 ; CHECK-LABEL: func_h: 41 ; CHECK-NOT: cmp 42 ; CHECK: cmov 43 ; CHECK-NOT: movl 44 ; CHECK: ret 45 %cmp = icmp slt i32 %b, %a 46 %sub = sub nsw i32 %a, %b 47 %cond = select i1 %cmp, i32 %sub, i32 0 48 ret i32 %cond 49 } 50 define i32 @func_i(i32 %a, i32 %b) nounwind { 51 entry: 52 ; CHECK-LABEL: func_i: 53 ; CHECK-NOT: cmp 54 ; CHECK: cmov 55 ; CHECK-NOT: movl 56 ; CHECK: ret 57 %cmp = icmp sgt i32 %a, %b 58 %sub = sub nsw i32 %a, %b 59 %cond = select i1 %cmp, i32 %sub, i32 0 60 ret i32 %cond 61 } 62 define i32 @func_j(i32 %a, i32 %b) nounwind { 63 entry: 64 ; CHECK-LABEL: func_j: 65 ; CHECK-NOT: cmp 66 ; CHECK: cmov 67 ; CHECK-NOT: movl 68 ; CHECK: ret 69 %cmp = icmp ugt i32 %a, %b 70 %sub = sub i32 %a, %b 71 %cond = select i1 %cmp, i32 %sub, i32 0 72 ret i32 %cond 73 } 74 define i32 @func_k(i32 %a, i32 %b) nounwind { 75 entry: 76 ; CHECK-LABEL: func_k: 77 ; CHECK-NOT: cmp 78 ; CHECK: cmov 79 ; CHECK-NOT: movl 80 ; CHECK: ret 81 %cmp = icmp ult i32 %b, %a 82 %sub = sub i32 %a, %b 83 %cond = select i1 %cmp, i32 %sub, i32 0 84 ret i32 %cond 85 } 86 ; redundant cmp instruction 87 define i32 @func_l(i32 %a, i32 %b) nounwind { 88 entry: 89 ; CHECK-LABEL: func_l: 90 ; CHECK-NOT: cmp 91 %cmp = icmp slt i32 %b, %a 92 %sub = sub nsw i32 %a, %b 93 %cond = select i1 %cmp, i32 %sub, i32 %a 94 ret i32 %cond 95 } 96 define i32 @func_m(i32 %a, i32 %b) nounwind { 97 entry: 98 ; CHECK-LABEL: func_m: 99 ; CHECK-NOT: cmp 100 %cmp = icmp sgt i32 %a, %b 101 %sub = sub nsw i32 %a, %b 102 %cond = select i1 %cmp, i32 %b, i32 %sub 103 ret i32 %cond 104 } 105 ; If EFLAGS is live-out, we can't remove cmp if there exists 106 ; a swapped sub. 107 define i32 @func_l2(i32 %a, i32 %b) nounwind { 108 entry: 109 ; CHECK-LABEL: func_l2: 110 ; CHECK: cmp 111 %cmp = icmp eq i32 %b, %a 112 %sub = sub nsw i32 %a, %b 113 br i1 %cmp, label %if.then, label %if.else 114 115 if.then: 116 %cmp2 = icmp sgt i32 %b, %a 117 %sel = select i1 %cmp2, i32 %sub, i32 %a 118 ret i32 %sel 119 120 if.else: 121 ret i32 %sub 122 } 123 define i32 @func_l3(i32 %a, i32 %b) nounwind { 124 entry: 125 ; CHECK-LABEL: func_l3: 126 ; CHECK: sub 127 ; CHECK-NOT: cmp 128 ; CHECK: jge 129 %cmp = icmp sgt i32 %b, %a 130 %sub = sub nsw i32 %a, %b 131 br i1 %cmp, label %if.then, label %if.else 132 133 if.then: 134 ret i32 %sub 135 136 if.else: 137 %add = add nsw i32 %sub, 1 138 ret i32 %add 139 } 140 ; rdar://11830760 141 ; When Movr0 is between sub and cmp, we need to move "Movr0" before sub. 142 define i32 @func_l4(i32 %a, i32 %b) nounwind { 143 entry: 144 ; CHECK-LABEL: func_l4: 145 ; CHECK: xor 146 ; CHECK: sub 147 ; CHECK-NOT: cmp 148 %cmp = icmp sgt i32 %b, %a 149 %sub = sub i32 %a, %b 150 %.sub = select i1 %cmp, i32 0, i32 %sub 151 ret i32 %.sub 152 } 153 ; rdar://11540023 154 define i32 @func_n(i32 %x, i32 %y) nounwind { 155 entry: 156 ; CHECK-LABEL: func_n: 157 ; CHECK-NOT: sub 158 ; CHECK: cmp 159 %sub = sub nsw i32 %x, %y 160 %cmp = icmp slt i32 %sub, 0 161 %y.x = select i1 %cmp, i32 %y, i32 %x 162 ret i32 %y.x 163 } 164 ; PR://13046 165 define void @func_o() nounwind uwtable { 166 entry: 167 %0 = load i16, i16* undef, align 2 168 br i1 undef, label %if.then.i, label %if.end.i 169 170 if.then.i: ; preds = %entry 171 unreachable 172 173 if.end.i: ; preds = %entry 174 br i1 undef, label %sw.bb, label %sw.default 175 176 sw.bb: ; preds = %if.end.i 177 br i1 undef, label %if.then44, label %if.end29 178 179 if.end29: ; preds = %sw.bb 180 ; CHECK-LABEL: func_o: 181 ; CHECK: cmp 182 %1 = urem i16 %0, 10 183 %cmp25 = icmp eq i16 %1, 0 184 %. = select i1 %cmp25, i16 2, i16 0 185 br i1 %cmp25, label %if.then44, label %sw.default 186 187 sw.default: ; preds = %if.end29, %if.end.i 188 br i1 undef, label %if.then.i96, label %if.else.i97 189 190 if.then.i96: ; preds = %sw.default 191 unreachable 192 193 if.else.i97: ; preds = %sw.default 194 unreachable 195 196 if.then44: ; preds = %if.end29, %sw.bb 197 %aModeRefSel.1.ph = phi i16 [ %., %if.end29 ], [ 3, %sw.bb ] 198 br i1 undef, label %if.then.i103, label %if.else.i104 199 200 if.then.i103: ; preds = %if.then44 201 unreachable 202 203 if.else.i104: ; preds = %if.then44 204 ret void 205 } 206 ; rdar://11855129 207 define i32 @func_p(i32 %a, i32 %b) nounwind { 208 entry: 209 ; CHECK-LABEL: func_p: 210 ; CHECK-NOT: test 211 ; CHECK: cmovs 212 %add = add nsw i32 %b, %a 213 %cmp = icmp sgt i32 %add, 0 214 %add. = select i1 %cmp, i32 %add, i32 0 215 ret i32 %add. 216 } 217 ; PR13475 218 ; If we have sub a, b and cmp b, a and the result of cmp is used 219 ; by sbb, we should not optimize cmp away. 220 define i32 @func_q(i32 %a0, i32 %a1, i32 %a2) { 221 ; CHECK-LABEL: func_q: 222 ; CHECK: cmp 223 ; CHECK-NEXT: sbb 224 %1 = icmp ult i32 %a0, %a1 225 %2 = sub i32 %a1, %a0 226 %3 = select i1 %1, i32 -1, i32 0 227 %4 = xor i32 %2, %3 228 ret i32 %4 229 } 230 ; rdar://11873276 231 define i8* @func_r(i8* %base, i32* nocapture %offset, i32 %size) nounwind { 232 entry: 233 ; CHECK-LABEL: func_r: 234 ; CHECK: sub 235 ; CHECK-NOT: cmp 236 ; CHECK: j 237 ; CHECK-NOT: sub 238 ; CHECK: ret 239 %0 = load i32, i32* %offset, align 8 240 %cmp = icmp slt i32 %0, %size 241 br i1 %cmp, label %return, label %if.end 242 243 if.end: 244 %sub = sub nsw i32 %0, %size 245 store i32 %sub, i32* %offset, align 8 246 %add.ptr = getelementptr inbounds i8, i8* %base, i32 %sub 247 br label %return 248 249 return: 250 %retval.0 = phi i8* [ %add.ptr, %if.end ], [ null, %entry ] 251 ret i8* %retval.0 252 } 253 254 ; Test optimizations of dec/inc. 255 define i32 @func_dec(i32 %a) nounwind { 256 entry: 257 ; CHECK-LABEL: func_dec: 258 ; CHECK: decl 259 ; CHECK-NOT: test 260 ; CHECK: cmovsl 261 %sub = sub nsw i32 %a, 1 262 %cmp = icmp sgt i32 %sub, 0 263 %cond = select i1 %cmp, i32 %sub, i32 0 264 ret i32 %cond 265 } 266 267 define i32 @func_inc(i32 %a) nounwind { 268 entry: 269 ; CHECK-LABEL: func_inc: 270 ; CHECK: incl 271 ; CHECK-NOT: test 272 ; CHECK: cmovsl 273 %add = add nsw i32 %a, 1 274 %cmp = icmp sgt i32 %add, 0 275 %cond = select i1 %cmp, i32 %add, i32 0 276 ret i32 %cond 277 } 278 279 ; PR13966 280 @b = common global i32 0, align 4 281 @a = common global i32 0, align 4 282 define i32 @func_test1(i32 %p1) nounwind uwtable { 283 entry: 284 ; CHECK-LABEL: func_test1: 285 ; CHECK: andb 286 ; CHECK: j 287 ; CHECK: ret 288 %0 = load i32, i32* @b, align 4 289 %cmp = icmp ult i32 %0, %p1 290 %conv = zext i1 %cmp to i32 291 %1 = load i32, i32* @a, align 4 292 %and = and i32 %conv, %1 293 %conv1 = trunc i32 %and to i8 294 %2 = urem i8 %conv1, 3 295 %tobool = icmp eq i8 %2, 0 296 br i1 %tobool, label %if.end, label %if.then 297 298 if.then: 299 %dec = add nsw i32 %1, -1 300 store i32 %dec, i32* @a, align 4 301 br label %if.end 302 303 if.end: 304 ret i32 undef 305 } 306