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* %p 9 %t1 = load %0* %q 10 %t4 = select i1 %r, %0 %t0, %0 %t1 11 %t5 = extractvalue %0 %t4, 1 12 ret i32 %t5 13; CHECK: test1: 14; CHECK: cmovneq %rdi, %rsi 15; CHECK: movl (%rsi), %eax 16 17; ATOM: 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: test2: 37; CHECK: movnew 38; CHECK: movswl 39 40; ATOM: test2: 41; ATOM: movnew 42; ATOM: movswl 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: test3: 55; CHECK: movss {{.*}},4), %xmm0 56 57; ATOM: 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* %P, i32 %iftmp.0.0 ; <i8*> [#uses=1] 66 %2 = load i8* %1, align 1 ; <i8> [#uses=1] 67 ret i8 %2 68; CHECK: test4: 69; CHECK: movsbl ({{.*}},4), %eax 70 71; ATOM: 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: test5: 80 81; ATOM: test5: 82} 83 84define void @test6(i32 %C, <4 x float>* %A, <4 x float>* %B) nounwind { 85 %tmp = load <4 x float>* %A ; <<4 x float>> [#uses=1] 86 %tmp3 = load <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: test6: 95; CHECK: je 96; CHECK: ret 97; CHECK: mulps 98; CHECK: ret 99 100; ATOM: 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: test7: 113; CHECK: leaq 114; CHECK: fldt (%r{{.}}x,%r{{.}}x) 115 116; ATOM: 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: test8: 129 130; ATOM: 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: test9: 141; CHECK: cmpq $1, %rdi 142; CHECK: sbbq %rax, %rax 143; CHECK: orq %rsi, %rax 144; CHECK: ret 145 146; ATOM: 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: test9a: 159; CHECK: cmpq $1, %rdi 160; CHECK: sbbq %rax, %rax 161; CHECK: orq %rsi, %rax 162; CHECK: ret 163 164; ATOM: 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: test9b: 177; CHECK: cmpq $1, %rdi 178; CHECK: sbbq %rax, %rax 179; CHECK: orq %rsi, %rax 180; CHECK: ret 181 182; ATOM: 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: test10: 195; CHECK: cmpq $1, %rdi 196; CHECK: sbbq %rax, %rax 197; CHECK: orq $1, %rax 198; CHECK: ret 199 200; ATOM: 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: 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: 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: 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: 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: test12: 259; CHECK: movq $-1, %rdi 260; CHECK: mulq 261; CHECK: cmovnoq %rax, %rdi 262; CHECK: jmp __Znam 263 264; ATOM: 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: test13: 278; CHECK: cmpl 279; CHECK-NEXT: sbbl 280; CHECK-NEXT: ret 281 282; ATOM: 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: test14: 293; CHECK: cmpl 294; CHECK-NEXT: sbbl 295; CHECK-NEXT: notl 296; CHECK-NEXT: ret 297 298; ATOM: 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: test15: 312; CHECK: negl 313; CHECK: sbbl 314 315; ATOM: 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: test16: 326; CHECK: negq 327; CHECK: sbbq 328 329; ATOM: 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: test17: 340; CHECK: negw 341; CHECK: sbbw 342 343; ATOM: 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: test18: 353; CHECK: cmpl $15, %edi 354; CHECK: cmovgel %edx 355 356; ATOM: test18: 357; ATOM: cmpl $15, %edi 358; ATOM: cmovgel %edx 359} 360