1; RUN: llc < %s -mtriple=x86_64-apple-darwin10 -mcpu=generic | FileCheck %s 2; RUN: llc < %s -mtriple=x86_64-apple-darwin10 -mcpu=atom | FileCheck -check-prefix=ATOM %s 3; PR5757 4 5%0 = type { i64, i32 } 6 7define i32 @test1(%0* %p, %0* %q, i1 %r) nounwind { 8 %t0 = load %0, %0* %p 9 %t1 = load %0, %0* %q 10 %t4 = select i1 %r, %0 %t0, %0 %t1 11 %t5 = extractvalue %0 %t4, 1 12 ret i32 %t5 13; CHECK-LABEL: test1: 14; CHECK: cmovneq %rdi, %rsi 15; CHECK: movl (%rsi), %eax 16 17; ATOM-LABEL: test1: 18; ATOM: cmovneq %rdi, %rsi 19; ATOM: movl (%rsi), %eax 20} 21 22 23; PR2139 24define i32 @test2() nounwind { 25entry: 26 %tmp73 = tail call i1 @return_false() ; <i8> [#uses=1] 27 %g.0 = select i1 %tmp73, i16 0, i16 -480 ; <i16> [#uses=2] 28 %tmp7778 = sext i16 %g.0 to i32 ; <i32> [#uses=1] 29 %tmp80 = shl i32 %tmp7778, 3 ; <i32> [#uses=2] 30 %tmp87 = icmp sgt i32 %tmp80, 32767 ; <i1> [#uses=1] 31 br i1 %tmp87, label %bb90, label %bb91 32bb90: ; preds = %bb84, %bb72 33 unreachable 34bb91: ; preds = %bb84 35 ret i32 0 36; CHECK-LABEL: test2: 37; CHECK: cmovnew 38; CHECK: cwtl 39 40; ATOM-LABEL: test2: 41; ATOM: cmovnew 42; ATOM: cwtl 43} 44 45declare i1 @return_false() 46 47 48;; Select between two floating point constants. 49define float @test3(i32 %x) nounwind readnone { 50entry: 51 %0 = icmp eq i32 %x, 0 ; <i1> [#uses=1] 52 %iftmp.0.0 = select i1 %0, float 4.200000e+01, float 2.300000e+01 ; <float> [#uses=1] 53 ret float %iftmp.0.0 54; CHECK-LABEL: test3: 55; CHECK: movss {{.*}},4), %xmm0 56 57; ATOM-LABEL: test3: 58; ATOM: movss {{.*}},4), %xmm0 59} 60 61define signext i8 @test4(i8* nocapture %P, double %F) nounwind readonly { 62entry: 63 %0 = fcmp olt double %F, 4.200000e+01 ; <i1> [#uses=1] 64 %iftmp.0.0 = select i1 %0, i32 4, i32 0 ; <i32> [#uses=1] 65 %1 = getelementptr i8, i8* %P, i32 %iftmp.0.0 ; <i8*> [#uses=1] 66 %2 = load i8, i8* %1, align 1 ; <i8> [#uses=1] 67 ret i8 %2 68; CHECK-LABEL: test4: 69; CHECK: movsbl ({{.*}},4), %eax 70 71; ATOM-LABEL: test4: 72; ATOM: movsbl ({{.*}},4), %eax 73} 74 75define void @test5(i1 %c, <2 x i16> %a, <2 x i16> %b, <2 x i16>* %p) nounwind { 76 %x = select i1 %c, <2 x i16> %a, <2 x i16> %b 77 store <2 x i16> %x, <2 x i16>* %p 78 ret void 79; CHECK-LABEL: test5: 80 81; ATOM-LABEL: test5: 82} 83 84define void @test6(i32 %C, <4 x float>* %A, <4 x float>* %B) nounwind { 85 %tmp = load <4 x float>, <4 x float>* %A ; <<4 x float>> [#uses=1] 86 %tmp3 = load <4 x float>, <4 x float>* %B ; <<4 x float>> [#uses=2] 87 %tmp9 = fmul <4 x float> %tmp3, %tmp3 ; <<4 x float>> [#uses=1] 88 %tmp.upgrd.1 = icmp eq i32 %C, 0 ; <i1> [#uses=1] 89 %iftmp.38.0 = select i1 %tmp.upgrd.1, <4 x float> %tmp9, <4 x float> %tmp ; <<4 x float>> [#uses=1] 90 store <4 x float> %iftmp.38.0, <4 x float>* %A 91 ret void 92; Verify that the fmul gets sunk into the one part of the diamond where it is 93; needed. 94; CHECK-LABEL: test6: 95; CHECK: je 96; CHECK: ret 97; CHECK: mulps 98; CHECK: ret 99 100; ATOM-LABEL: test6: 101; ATOM: je 102; ATOM: ret 103; ATOM: mulps 104; ATOM: ret 105} 106 107; Select with fp80's 108define x86_fp80 @test7(i32 %tmp8) nounwind { 109 %tmp9 = icmp sgt i32 %tmp8, -1 ; <i1> [#uses=1] 110 %retval = select i1 %tmp9, x86_fp80 0xK4005B400000000000000, x86_fp80 0xK40078700000000000000 111 ret x86_fp80 %retval 112; CHECK-LABEL: test7: 113; CHECK: leaq 114; CHECK: fldt (%r{{.}}x,%r{{.}}x) 115 116; ATOM-LABEL: test7: 117; ATOM: leaq 118; ATOM: fldt (%r{{.}}x,%r{{.}}x) 119} 120 121; widening select v6i32 and then a sub 122define void @test8(i1 %c, <6 x i32>* %dst.addr, <6 x i32> %src1,<6 x i32> %src2) nounwind { 123 %x = select i1 %c, <6 x i32> %src1, <6 x i32> %src2 124 %val = sub <6 x i32> %x, < i32 1, i32 1, i32 1, i32 1, i32 1, i32 1 > 125 store <6 x i32> %val, <6 x i32>* %dst.addr 126 ret void 127 128; CHECK-LABEL: test8: 129 130; ATOM-LABEL: test8: 131} 132 133 134;; Test integer select between values and constants. 135 136define i64 @test9(i64 %x, i64 %y) nounwind readnone ssp noredzone { 137 %cmp = icmp ne i64 %x, 0 138 %cond = select i1 %cmp, i64 %y, i64 -1 139 ret i64 %cond 140; CHECK-LABEL: test9: 141; CHECK: cmpq $1, %rdi 142; CHECK: sbbq %rax, %rax 143; CHECK: orq %rsi, %rax 144; CHECK: ret 145 146; ATOM-LABEL: test9: 147; ATOM: cmpq $1, %rdi 148; ATOM: sbbq %rax, %rax 149; ATOM: orq %rsi, %rax 150; ATOM: ret 151} 152 153;; Same as test9 154define i64 @test9a(i64 %x, i64 %y) nounwind readnone ssp noredzone { 155 %cmp = icmp eq i64 %x, 0 156 %cond = select i1 %cmp, i64 -1, i64 %y 157 ret i64 %cond 158; CHECK-LABEL: test9a: 159; CHECK: cmpq $1, %rdi 160; CHECK: sbbq %rax, %rax 161; CHECK: orq %rsi, %rax 162; CHECK: ret 163 164; ATOM-LABEL: test9a: 165; ATOM: cmpq $1, %rdi 166; ATOM: sbbq %rax, %rax 167; ATOM: orq %rsi, %rax 168; ATOM: ret 169} 170 171define i64 @test9b(i64 %x, i64 %y) nounwind readnone ssp noredzone { 172 %cmp = icmp eq i64 %x, 0 173 %A = sext i1 %cmp to i64 174 %cond = or i64 %y, %A 175 ret i64 %cond 176; CHECK-LABEL: test9b: 177; CHECK: cmpq $1, %rdi 178; CHECK: sbbq %rax, %rax 179; CHECK: orq %rsi, %rax 180; CHECK: ret 181 182; ATOM-LABEL: test9b: 183; ATOM: cmpq $1, %rdi 184; ATOM: sbbq %rax, %rax 185; ATOM: orq %rsi, %rax 186; ATOM: ret 187} 188 189;; Select between -1 and 1. 190define i64 @test10(i64 %x, i64 %y) nounwind readnone ssp noredzone { 191 %cmp = icmp eq i64 %x, 0 192 %cond = select i1 %cmp, i64 -1, i64 1 193 ret i64 %cond 194; CHECK-LABEL: test10: 195; CHECK: cmpq $1, %rdi 196; CHECK: sbbq %rax, %rax 197; CHECK: orq $1, %rax 198; CHECK: ret 199 200; ATOM-LABEL: test10: 201; ATOM: cmpq $1, %rdi 202; ATOM: sbbq %rax, %rax 203; ATOM: orq $1, %rax 204; ATOM: ret 205} 206 207 208 209define i64 @test11(i64 %x, i64 %y) nounwind readnone ssp noredzone { 210 %cmp = icmp eq i64 %x, 0 211 %cond = select i1 %cmp, i64 %y, i64 -1 212 ret i64 %cond 213; CHECK-LABEL: test11: 214; CHECK: cmpq $1, %rdi 215; CHECK: sbbq %rax, %rax 216; CHECK: notq %rax 217; CHECK: orq %rsi, %rax 218; CHECK: ret 219 220; ATOM-LABEL: test11: 221; ATOM: cmpq $1, %rdi 222; ATOM: sbbq %rax, %rax 223; ATOM: notq %rax 224; ATOM: orq %rsi, %rax 225; ATOM: ret 226} 227 228define i64 @test11a(i64 %x, i64 %y) nounwind readnone ssp noredzone { 229 %cmp = icmp ne i64 %x, 0 230 %cond = select i1 %cmp, i64 -1, i64 %y 231 ret i64 %cond 232; CHECK-LABEL: test11a: 233; CHECK: cmpq $1, %rdi 234; CHECK: sbbq %rax, %rax 235; CHECK: notq %rax 236; CHECK: orq %rsi, %rax 237; CHECK: ret 238 239; ATOM-LABEL: test11a: 240; ATOM: cmpq $1, %rdi 241; ATOM: sbbq %rax, %rax 242; ATOM: notq %rax 243; ATOM: orq %rsi, %rax 244; ATOM: ret 245} 246 247 248declare noalias i8* @_Znam(i64) noredzone 249 250define noalias i8* @test12(i64 %count) nounwind ssp noredzone { 251entry: 252 %A = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %count, i64 4) 253 %B = extractvalue { i64, i1 } %A, 1 254 %C = extractvalue { i64, i1 } %A, 0 255 %D = select i1 %B, i64 -1, i64 %C 256 %call = tail call noalias i8* @_Znam(i64 %D) nounwind noredzone 257 ret i8* %call 258; CHECK-LABEL: test12: 259; CHECK: mulq 260; CHECK: movq $-1, %[[R:r..]] 261; CHECK: cmovnoq %rax, %[[R]] 262; CHECK: jmp __Znam 263 264; ATOM-LABEL: test12: 265; ATOM: mulq 266; ATOM: movq $-1, %rdi 267; ATOM: cmovnoq %rax, %rdi 268; ATOM: jmp __Znam 269} 270 271declare { i64, i1 } @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone 272 273define i32 @test13(i32 %a, i32 %b) nounwind { 274 %c = icmp ult i32 %a, %b 275 %d = sext i1 %c to i32 276 ret i32 %d 277; CHECK-LABEL: test13: 278; CHECK: cmpl 279; CHECK-NEXT: sbbl 280; CHECK-NEXT: ret 281 282; ATOM-LABEL: test13: 283; ATOM: cmpl 284; ATOM-NEXT: sbbl 285; ATOM: ret 286} 287 288define i32 @test14(i32 %a, i32 %b) nounwind { 289 %c = icmp uge i32 %a, %b 290 %d = sext i1 %c to i32 291 ret i32 %d 292; CHECK-LABEL: test14: 293; CHECK: cmpl 294; CHECK-NEXT: sbbl 295; CHECK-NEXT: notl 296; CHECK-NEXT: ret 297 298; ATOM-LABEL: test14: 299; ATOM: cmpl 300; ATOM-NEXT: sbbl 301; ATOM-NEXT: notl 302; ATOM: ret 303} 304 305; rdar://10961709 306define i32 @test15(i32 %x) nounwind { 307entry: 308 %cmp = icmp ne i32 %x, 0 309 %sub = sext i1 %cmp to i32 310 ret i32 %sub 311; CHECK-LABEL: test15: 312; CHECK: negl 313; CHECK: sbbl 314 315; ATOM-LABEL: test15: 316; ATOM: negl 317; ATOM: sbbl 318} 319 320define i64 @test16(i64 %x) nounwind uwtable readnone ssp { 321entry: 322 %cmp = icmp ne i64 %x, 0 323 %conv1 = sext i1 %cmp to i64 324 ret i64 %conv1 325; CHECK-LABEL: test16: 326; CHECK: negq 327; CHECK: sbbq 328 329; ATOM-LABEL: test16: 330; ATOM: negq 331; ATOM: sbbq 332} 333 334define i16 @test17(i16 %x) nounwind { 335entry: 336 %cmp = icmp ne i16 %x, 0 337 %sub = sext i1 %cmp to i16 338 ret i16 %sub 339; CHECK-LABEL: test17: 340; CHECK: negw 341; CHECK: sbbw 342 343; ATOM-LABEL: test17: 344; ATOM: negw 345; ATOM: sbbw 346} 347 348define i8 @test18(i32 %x, i8 zeroext %a, i8 zeroext %b) nounwind { 349 %cmp = icmp slt i32 %x, 15 350 %sel = select i1 %cmp, i8 %a, i8 %b 351 ret i8 %sel 352; CHECK-LABEL: test18: 353; CHECK: cmpl $15, %edi 354; CHECK: cmovgel %edx 355 356; ATOM-LABEL: test18: 357; ATOM: cmpl $15, %edi 358; ATOM: cmovgel %edx 359} 360 361; CHECK-LABEL: @trunc_select_miscompile 362; CHECK-NOT: sarb 363define i32 @trunc_select_miscompile(i32 %a, i1 zeroext %cc) { 364 %tmp1 = select i1 %cc, i32 3, i32 2 365 %tmp2 = shl i32 %a, %tmp1 366 ret i32 %tmp2 367} 368 369define void @test19() { 370; This is a massive reduction of an llvm-stress test case that generates 371; interesting chains feeding setcc and eventually a f32 select operation. This 372; is intended to exercise the SELECT formation in the DAG combine simplifying 373; a simplified select_cc node. If it it regresses and is no longer triggering 374; that code path, it can be deleted. 375; 376; CHECK-LABEL: @test19 377; CHECK: testb 378; CHECK: cmpl 379; CHECK: ucomiss 380 381BB: 382 br label %CF 383 384CF: 385 %Cmp10 = icmp ule i8 undef, undef 386 br i1 %Cmp10, label %CF, label %CF250 387 388CF250: 389 %E12 = extractelement <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, i32 2 390 %Cmp32 = icmp ugt i1 %Cmp10, false 391 br i1 %Cmp32, label %CF, label %CF242 392 393CF242: 394 %Cmp38 = icmp uge i32 %E12, undef 395 %FC = uitofp i1 %Cmp38 to float 396 %Sl59 = select i1 %Cmp32, float %FC, float undef 397 %Cmp60 = fcmp ugt float undef, undef 398 br i1 %Cmp60, label %CF242, label %CF244 399 400CF244: 401 %B122 = fadd float %Sl59, undef 402 ret void 403} 404