1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=cmov -verify-machineinstrs | FileCheck %s 3 4define i32 @func_f(i32 %X) { 5; CHECK-LABEL: func_f: 6; CHECK: # %bb.0: # %entry 7; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 8; CHECK-NEXT: incl %eax 9; CHECK-NEXT: jns .LBB0_2 10; CHECK-NEXT: # %bb.1: # %cond_true 11; CHECK-NEXT: calll bar@PLT 12; CHECK-NEXT: .LBB0_2: # %cond_next 13; CHECK-NEXT: jmp baz@PLT # TAILCALL 14entry: 15 %tmp1 = add i32 %X, 1 16 %tmp = icmp slt i32 %tmp1, 0 17 br i1 %tmp, label %cond_true, label %cond_next, !prof !1 18 19cond_true: ; preds = %entry 20 %tmp2 = tail call i32 (...) @bar( ) 21 br label %cond_next 22 23cond_next: ; preds = %cond_true, %entry 24 %tmp3 = tail call i32 (...) @baz( ) 25 ret i32 undef 26} 27 28declare i32 @bar(...) 29declare i32 @baz(...) 30 31; rdar://10633221 32; rdar://11355268 33define i32 @func_g(i32 %a, i32 %b) nounwind { 34; CHECK-LABEL: func_g: 35; CHECK: # %bb.0: 36; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 37; CHECK-NEXT: xorl %ecx, %ecx 38; CHECK-NEXT: subl {{[0-9]+}}(%esp), %eax 39; CHECK-NEXT: cmovsl %ecx, %eax 40; CHECK-NEXT: retl 41 %sub = sub nsw i32 %a, %b 42 %cmp = icmp sgt i32 %sub, 0 43 %cond = select i1 %cmp, i32 %sub, i32 0 44 ret i32 %cond 45} 46 47; rdar://10734411 48define i32 @func_h(i32 %a, i32 %b) nounwind { 49; CHECK-LABEL: func_h: 50; CHECK: # %bb.0: 51; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 52; CHECK-NEXT: xorl %ecx, %ecx 53; CHECK-NEXT: subl {{[0-9]+}}(%esp), %eax 54; CHECK-NEXT: cmovlel %ecx, %eax 55; CHECK-NEXT: retl 56 %cmp = icmp slt i32 %b, %a 57 %sub = sub nsw i32 %a, %b 58 %cond = select i1 %cmp, i32 %sub, i32 0 59 ret i32 %cond 60} 61 62define i32 @func_i(i32 %a, i32 %b) nounwind { 63; CHECK-LABEL: func_i: 64; CHECK: # %bb.0: 65; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 66; CHECK-NEXT: xorl %ecx, %ecx 67; CHECK-NEXT: subl {{[0-9]+}}(%esp), %eax 68; CHECK-NEXT: cmovlel %ecx, %eax 69; CHECK-NEXT: retl 70 %cmp = icmp sgt i32 %a, %b 71 %sub = sub nsw i32 %a, %b 72 %cond = select i1 %cmp, i32 %sub, i32 0 73 ret i32 %cond 74} 75 76define i32 @func_j(i32 %a, i32 %b) nounwind { 77; CHECK-LABEL: func_j: 78; CHECK: # %bb.0: 79; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 80; CHECK-NEXT: xorl %ecx, %ecx 81; CHECK-NEXT: subl {{[0-9]+}}(%esp), %eax 82; CHECK-NEXT: cmovbel %ecx, %eax 83; CHECK-NEXT: retl 84 %cmp = icmp ugt i32 %a, %b 85 %sub = sub i32 %a, %b 86 %cond = select i1 %cmp, i32 %sub, i32 0 87 ret i32 %cond 88} 89 90define i32 @func_k(i32 %a, i32 %b) nounwind { 91; CHECK-LABEL: func_k: 92; CHECK: # %bb.0: 93; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 94; CHECK-NEXT: xorl %ecx, %ecx 95; CHECK-NEXT: subl {{[0-9]+}}(%esp), %eax 96; CHECK-NEXT: cmovbel %ecx, %eax 97; CHECK-NEXT: retl 98 %cmp = icmp ult i32 %b, %a 99 %sub = sub i32 %a, %b 100 %cond = select i1 %cmp, i32 %sub, i32 0 101 ret i32 %cond 102} 103 104; redundant cmp instruction 105define i32 @func_l(i32 %a, i32 %b) nounwind { 106; CHECK-LABEL: func_l: 107; CHECK: # %bb.0: 108; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 109; CHECK-NEXT: movl %ecx, %eax 110; CHECK-NEXT: subl {{[0-9]+}}(%esp), %eax 111; CHECK-NEXT: cmovlel %ecx, %eax 112; CHECK-NEXT: retl 113 %cmp = icmp slt i32 %b, %a 114 %sub = sub nsw i32 %a, %b 115 %cond = select i1 %cmp, i32 %sub, i32 %a 116 ret i32 %cond 117} 118 119define i32 @func_m(i32 %a, i32 %b) nounwind { 120; CHECK-LABEL: func_m: 121; CHECK: # %bb.0: 122; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 123; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 124; CHECK-NEXT: subl %ecx, %eax 125; CHECK-NEXT: cmovgl %ecx, %eax 126; CHECK-NEXT: retl 127 %cmp = icmp sgt i32 %a, %b 128 %sub = sub nsw i32 %a, %b 129 %cond = select i1 %cmp, i32 %b, i32 %sub 130 ret i32 %cond 131} 132 133; If EFLAGS is live-out, we can't remove cmp if there exists 134; a swapped sub. 135define i32 @func_l2(i32 %a, i32 %b) nounwind { 136; CHECK-LABEL: func_l2: 137; CHECK: # %bb.0: 138; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx 139; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 140; CHECK-NEXT: movl %ecx, %eax 141; CHECK-NEXT: subl %edx, %eax 142; CHECK-NEXT: jne .LBB8_2 143; CHECK-NEXT: # %bb.1: # %if.then 144; CHECK-NEXT: cmpl %ecx, %edx 145; CHECK-NEXT: cmovlel %ecx, %eax 146; CHECK-NEXT: .LBB8_2: # %if.else 147; CHECK-NEXT: retl 148 %cmp = icmp eq i32 %b, %a 149 %sub = sub nsw i32 %a, %b 150 br i1 %cmp, label %if.then, label %if.else 151 152if.then: 153 %cmp2 = icmp sgt i32 %b, %a 154 %sel = select i1 %cmp2, i32 %sub, i32 %a 155 ret i32 %sel 156 157if.else: 158 ret i32 %sub 159} 160 161define i32 @func_l3(i32 %a, i32 %b) nounwind { 162; CHECK-LABEL: func_l3: 163; CHECK: # %bb.0: 164; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 165; CHECK-NEXT: subl {{[0-9]+}}(%esp), %eax 166; CHECK-NEXT: jge .LBB9_2 167; CHECK-NEXT: # %bb.1: # %if.then 168; CHECK-NEXT: retl 169; CHECK-NEXT: .LBB9_2: # %if.else 170; CHECK-NEXT: incl %eax 171; CHECK-NEXT: retl 172 %cmp = icmp sgt i32 %b, %a 173 %sub = sub nsw i32 %a, %b 174 br i1 %cmp, label %if.then, label %if.else 175 176if.then: 177 ret i32 %sub 178 179if.else: 180 %add = add nsw i32 %sub, 1 181 ret i32 %add 182} 183 184; rdar://11830760 185; When Movr0 is between sub and cmp, we need to move "Movr0" before sub. 186define i32 @func_l4(i32 %a, i32 %b) nounwind { 187; CHECK-LABEL: func_l4: 188; CHECK: # %bb.0: 189; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 190; CHECK-NEXT: xorl %ecx, %ecx 191; CHECK-NEXT: subl {{[0-9]+}}(%esp), %eax 192; CHECK-NEXT: cmovll %ecx, %eax 193; CHECK-NEXT: retl 194 %cmp = icmp sgt i32 %b, %a 195 %sub = sub i32 %a, %b 196 %.sub = select i1 %cmp, i32 0, i32 %sub 197 ret i32 %.sub 198} 199 200; rdar://11540023 201define i32 @func_n(i32 %x, i32 %y) nounwind { 202; CHECK-LABEL: func_n: 203; CHECK: # %bb.0: 204; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 205; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 206; CHECK-NEXT: cmpl %ecx, %eax 207; CHECK-NEXT: cmovsl %ecx, %eax 208; CHECK-NEXT: retl 209 %sub = sub nsw i32 %x, %y 210 %cmp = icmp slt i32 %sub, 0 211 %y.x = select i1 %cmp, i32 %y, i32 %x 212 ret i32 %y.x 213} 214 215; PR://13046 216define void @func_o() nounwind uwtable { 217; CHECK-LABEL: func_o: 218; CHECK: # %bb.0: # %entry 219; CHECK-NEXT: xorl %eax, %eax 220; CHECK-NEXT: testb %al, %al 221; CHECK-NEXT: je .LBB12_1 222; CHECK-NEXT: # %bb.2: # %if.end.i 223; CHECK-NEXT: xorl %eax, %eax 224; CHECK-NEXT: testb %al, %al 225; CHECK-NEXT: jne .LBB12_5 226; CHECK-NEXT: # %bb.3: # %sw.bb 227; CHECK-NEXT: xorl %eax, %eax 228; CHECK-NEXT: testb %al, %al 229; CHECK-NEXT: jne .LBB12_8 230; CHECK-NEXT: # %bb.4: # %if.end29 231; CHECK-NEXT: movzwl (%eax), %eax 232; CHECK-NEXT: imull $-13107, %eax, %eax # imm = 0xCCCD 233; CHECK-NEXT: rorw %ax 234; CHECK-NEXT: movzwl %ax, %eax 235; CHECK-NEXT: cmpl $6554, %eax # imm = 0x199A 236; CHECK-NEXT: jae .LBB12_5 237; CHECK-NEXT: .LBB12_8: # %if.then44 238; CHECK-NEXT: xorl %eax, %eax 239; CHECK-NEXT: testb %al, %al 240; CHECK-NEXT: je .LBB12_9 241; CHECK-NEXT: # %bb.10: # %if.else.i104 242; CHECK-NEXT: retl 243; CHECK-NEXT: .LBB12_5: # %sw.default 244; CHECK-NEXT: xorl %eax, %eax 245; CHECK-NEXT: testb %al, %al 246; CHECK-NEXT: jne .LBB12_7 247; CHECK-NEXT: # %bb.6: # %if.then.i96 248; CHECK-NEXT: .LBB12_1: # %if.then.i 249; CHECK-NEXT: .LBB12_9: # %if.then.i103 250; CHECK-NEXT: .LBB12_7: # %if.else.i97 251entry: 252 %0 = load i16, i16* undef, align 2 253 br i1 undef, label %if.then.i, label %if.end.i 254 255if.then.i: ; preds = %entry 256 unreachable 257 258if.end.i: ; preds = %entry 259 br i1 undef, label %sw.bb, label %sw.default 260 261sw.bb: ; preds = %if.end.i 262 br i1 undef, label %if.then44, label %if.end29 263 264if.end29: ; preds = %sw.bb 265 %1 = urem i16 %0, 10 266 %cmp25 = icmp eq i16 %1, 0 267 %. = select i1 %cmp25, i16 2, i16 0 268 br i1 %cmp25, label %if.then44, label %sw.default 269 270sw.default: ; preds = %if.end29, %if.end.i 271 br i1 undef, label %if.then.i96, label %if.else.i97 272 273if.then.i96: ; preds = %sw.default 274 unreachable 275 276if.else.i97: ; preds = %sw.default 277 unreachable 278 279if.then44: ; preds = %if.end29, %sw.bb 280 %aModeRefSel.1.ph = phi i16 [ %., %if.end29 ], [ 3, %sw.bb ] 281 br i1 undef, label %if.then.i103, label %if.else.i104 282 283if.then.i103: ; preds = %if.then44 284 unreachable 285 286if.else.i104: ; preds = %if.then44 287 ret void 288} 289 290; rdar://11855129 291define i32 @func_p(i32 %a, i32 %b) nounwind { 292; CHECK-LABEL: func_p: 293; CHECK: # %bb.0: 294; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 295; CHECK-NEXT: xorl %ecx, %ecx 296; CHECK-NEXT: addl {{[0-9]+}}(%esp), %eax 297; CHECK-NEXT: cmovsl %ecx, %eax 298; CHECK-NEXT: retl 299 %add = add nsw i32 %b, %a 300 %cmp = icmp sgt i32 %add, 0 301 %add. = select i1 %cmp, i32 %add, i32 0 302 ret i32 %add. 303} 304 305; PR13475 306; We don't need an explicit cmp here. A sub/neg combo will do. 307 308define i32 @func_q(i32 %a0, i32 %a1, i32 %a2) { 309; CHECK-LABEL: func_q: 310; CHECK: # %bb.0: 311; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 312; CHECK-NEXT: subl {{[0-9]+}}(%esp), %eax 313; CHECK-NEXT: sbbl %ecx, %ecx 314; CHECK-NEXT: negl %eax 315; CHECK-NEXT: xorl %ecx, %eax 316; CHECK-NEXT: retl 317 %t1 = icmp ult i32 %a0, %a1 318 %t2 = sub i32 %a1, %a0 319 %t3 = select i1 %t1, i32 -1, i32 0 320 %t4 = xor i32 %t2, %t3 321 ret i32 %t4 322} 323 324; rdar://11873276 325define i8* @func_r(i8* %base, i32* nocapture %offset, i32 %size) nounwind { 326; CHECK-LABEL: func_r: 327; CHECK: # %bb.0: # %entry 328; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx 329; CHECK-NEXT: movl (%edx), %ecx 330; CHECK-NEXT: xorl %eax, %eax 331; CHECK-NEXT: subl {{[0-9]+}}(%esp), %ecx 332; CHECK-NEXT: jl .LBB15_2 333; CHECK-NEXT: # %bb.1: # %if.end 334; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 335; CHECK-NEXT: movl %ecx, (%edx) 336; CHECK-NEXT: addl %ecx, %eax 337; CHECK-NEXT: .LBB15_2: # %return 338; CHECK-NEXT: retl 339entry: 340 %0 = load i32, i32* %offset, align 8 341 %cmp = icmp slt i32 %0, %size 342 br i1 %cmp, label %return, label %if.end 343 344if.end: 345 %sub = sub nsw i32 %0, %size 346 store i32 %sub, i32* %offset, align 8 347 %add.ptr = getelementptr inbounds i8, i8* %base, i32 %sub 348 br label %return 349 350return: 351 %retval.0 = phi i8* [ %add.ptr, %if.end ], [ null, %entry ] 352 ret i8* %retval.0 353} 354 355; Test optimizations of dec/inc. 356define i32 @func_dec(i32 %a) nounwind { 357; CHECK-LABEL: func_dec: 358; CHECK: # %bb.0: 359; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 360; CHECK-NEXT: xorl %ecx, %ecx 361; CHECK-NEXT: decl %eax 362; CHECK-NEXT: cmovsl %ecx, %eax 363; CHECK-NEXT: retl 364 %sub = sub nsw i32 %a, 1 365 %cmp = icmp sgt i32 %sub, 0 366 %cond = select i1 %cmp, i32 %sub, i32 0 367 ret i32 %cond 368} 369 370define i32 @func_inc(i32 %a) nounwind { 371; CHECK-LABEL: func_inc: 372; CHECK: # %bb.0: 373; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 374; CHECK-NEXT: xorl %ecx, %ecx 375; CHECK-NEXT: incl %eax 376; CHECK-NEXT: cmovsl %ecx, %eax 377; CHECK-NEXT: retl 378 %add = add nsw i32 %a, 1 379 %cmp = icmp sgt i32 %add, 0 380 %cond = select i1 %cmp, i32 %add, i32 0 381 ret i32 %cond 382} 383 384; PR13966 385@b = common global i32 0, align 4 386@a = common global i32 0, align 4 387define i32 @func_test1(i32 %p1) nounwind uwtable { 388; CHECK-LABEL: func_test1: 389; CHECK: # %bb.0: # %entry 390; CHECK-NEXT: movl b, %eax 391; CHECK-NEXT: cmpl {{[0-9]+}}(%esp), %eax 392; CHECK-NEXT: setb %cl 393; CHECK-NEXT: movl a, %eax 394; CHECK-NEXT: testb %al, %cl 395; CHECK-NEXT: je .LBB18_2 396; CHECK-NEXT: # %bb.1: # %if.then 397; CHECK-NEXT: decl %eax 398; CHECK-NEXT: movl %eax, a 399; CHECK-NEXT: .LBB18_2: # %if.end 400; CHECK-NEXT: retl 401entry: 402 %t0 = load i32, i32* @b, align 4 403 %cmp = icmp ult i32 %t0, %p1 404 %conv = zext i1 %cmp to i32 405 %t1 = load i32, i32* @a, align 4 406 %and = and i32 %conv, %t1 407 %conv1 = trunc i32 %and to i8 408 %t2 = urem i8 %conv1, 3 409 %tobool = icmp eq i8 %t2, 0 410 br i1 %tobool, label %if.end, label %if.then 411 412if.then: 413 %dec = add nsw i32 %t1, -1 414 store i32 %dec, i32* @a, align 4 415 br label %if.end 416 417if.end: 418 ret i32 undef 419} 420 421!1 = !{!"branch_weights", i32 2, i32 1} 422 423