1; RUN: llc < %s -march=x86 -mcpu=pentiumpro -verify-machineinstrs | FileCheck %s 2 3define i32 @func_f(i32 %X) { 4entry: 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 11cond_true: ; preds = %entry 12 %tmp2 = tail call i32 (...) @bar( ) ; <i32> [#uses=0] 13 br label %cond_next 14 15cond_next: ; preds = %cond_true, %entry 16 %tmp3 = tail call i32 (...) @baz( ) ; <i32> [#uses=0] 17 ret i32 undef 18} 19 20declare i32 @bar(...) 21 22declare i32 @baz(...) 23 24; rdar://10633221 25; rdar://11355268 26define i32 @func_g(i32 %a, i32 %b) nounwind { 27entry: 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 38define i32 @func_h(i32 %a, i32 %b) nounwind { 39entry: 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} 50define i32 @func_i(i32 %a, i32 %b) nounwind { 51entry: 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} 62define i32 @func_j(i32 %a, i32 %b) nounwind { 63entry: 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} 74define i32 @func_k(i32 %a, i32 %b) nounwind { 75entry: 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 87define i32 @func_l(i32 %a, i32 %b) nounwind { 88entry: 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} 96define i32 @func_m(i32 %a, i32 %b) nounwind { 97entry: 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. 107define i32 @func_l2(i32 %a, i32 %b) nounwind { 108entry: 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 115if.then: 116 %cmp2 = icmp sgt i32 %b, %a 117 %sel = select i1 %cmp2, i32 %sub, i32 %a 118 ret i32 %sel 119 120if.else: 121 ret i32 %sub 122} 123define i32 @func_l3(i32 %a, i32 %b) nounwind { 124entry: 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 133if.then: 134 ret i32 %sub 135 136if.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. 142define i32 @func_l4(i32 %a, i32 %b) nounwind { 143entry: 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 154define i32 @func_n(i32 %x, i32 %y) nounwind { 155entry: 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 165define void @func_o() nounwind uwtable { 166entry: 167 %0 = load i16, i16* undef, align 2 168 br i1 undef, label %if.then.i, label %if.end.i 169 170if.then.i: ; preds = %entry 171 unreachable 172 173if.end.i: ; preds = %entry 174 br i1 undef, label %sw.bb, label %sw.default 175 176sw.bb: ; preds = %if.end.i 177 br i1 undef, label %if.then44, label %if.end29 178 179if.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 187sw.default: ; preds = %if.end29, %if.end.i 188 br i1 undef, label %if.then.i96, label %if.else.i97 189 190if.then.i96: ; preds = %sw.default 191 unreachable 192 193if.else.i97: ; preds = %sw.default 194 unreachable 195 196if.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 200if.then.i103: ; preds = %if.then44 201 unreachable 202 203if.else.i104: ; preds = %if.then44 204 ret void 205} 206; rdar://11855129 207define i32 @func_p(i32 %a, i32 %b) nounwind { 208entry: 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. 220define 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 231define i8* @func_r(i8* %base, i32* nocapture %offset, i32 %size) nounwind { 232entry: 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 243if.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 249return: 250 %retval.0 = phi i8* [ %add.ptr, %if.end ], [ null, %entry ] 251 ret i8* %retval.0 252} 253 254; Test optimizations of dec/inc. 255define i32 @func_dec(i32 %a) nounwind { 256entry: 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 267define i32 @func_inc(i32 %a) nounwind { 268entry: 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 282define i32 @func_test1(i32 %p1) nounwind uwtable { 283entry: 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 298if.then: 299 %dec = add nsw i32 %1, -1 300 store i32 %dec, i32* @a, align 4 301 br label %if.end 302 303if.end: 304 ret i32 undef 305} 306