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* 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 %j.4, i32 %w, i32 %el) { 221 ; CHECK-LABEL: func_q: 222 ; CHECK: cmp 223 ; CHECK-NEXT: sbb 224 %tmp532 = add i32 %j.4, %w 225 %tmp533 = icmp ugt i32 %tmp532, %el 226 %tmp534 = icmp ult i32 %w, %el 227 %or.cond = and i1 %tmp533, %tmp534 228 %tmp535 = sub i32 %el, %w 229 %j.5 = select i1 %or.cond, i32 %tmp535, i32 %j.4 230 ret i32 %j.5 231 } 232 ; rdar://11873276 233 define i8* @func_r(i8* %base, i32* nocapture %offset, i32 %size) nounwind { 234 entry: 235 ; CHECK-LABEL: func_r: 236 ; CHECK: sub 237 ; CHECK-NOT: cmp 238 ; CHECK: j 239 ; CHECK-NOT: sub 240 ; CHECK: ret 241 %0 = load i32* %offset, align 8 242 %cmp = icmp slt i32 %0, %size 243 br i1 %cmp, label %return, label %if.end 244 245 if.end: 246 %sub = sub nsw i32 %0, %size 247 store i32 %sub, i32* %offset, align 8 248 %add.ptr = getelementptr inbounds i8* %base, i32 %sub 249 br label %return 250 251 return: 252 %retval.0 = phi i8* [ %add.ptr, %if.end ], [ null, %entry ] 253 ret i8* %retval.0 254 } 255 256 ; Test optimizations of dec/inc. 257 define i32 @func_dec(i32 %a) nounwind { 258 entry: 259 ; CHECK-LABEL: func_dec: 260 ; CHECK: decl 261 ; CHECK-NOT: test 262 ; CHECK: cmovsl 263 %sub = sub nsw i32 %a, 1 264 %cmp = icmp sgt i32 %sub, 0 265 %cond = select i1 %cmp, i32 %sub, i32 0 266 ret i32 %cond 267 } 268 269 define i32 @func_inc(i32 %a) nounwind { 270 entry: 271 ; CHECK-LABEL: func_inc: 272 ; CHECK: incl 273 ; CHECK-NOT: test 274 ; CHECK: cmovsl 275 %add = add nsw i32 %a, 1 276 %cmp = icmp sgt i32 %add, 0 277 %cond = select i1 %cmp, i32 %add, i32 0 278 ret i32 %cond 279 } 280 281 ; PR13966 282 @b = common global i32 0, align 4 283 @a = common global i32 0, align 4 284 define i32 @func_test1(i32 %p1) nounwind uwtable { 285 entry: 286 ; CHECK-LABEL: func_test1: 287 ; CHECK: testb 288 ; CHECK: j 289 ; CHECK: ret 290 %0 = load i32* @b, align 4 291 %cmp = icmp ult i32 %0, %p1 292 %conv = zext i1 %cmp to i32 293 %1 = load i32* @a, align 4 294 %and = and i32 %conv, %1 295 %conv1 = trunc i32 %and to i8 296 %2 = urem i8 %conv1, 3 297 %tobool = icmp eq i8 %2, 0 298 br i1 %tobool, label %if.end, label %if.then 299 300 if.then: 301 %dec = add nsw i32 %1, -1 302 store i32 %dec, i32* @a, align 4 303 br label %if.end 304 305 if.end: 306 ret i32 undef 307 } 308