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 7 define 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 24 define i32 @test2() nounwind { 25 entry: 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 32 bb90: ; preds = %bb84, %bb72 33 unreachable 34 bb91: ; 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 45 declare i1 @return_false() 46 47 48 ;; Select between two floating point constants. 49 define float @test3(i32 %x) nounwind readnone { 50 entry: 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 61 define signext i8 @test4(i8* nocapture %P, double %F) nounwind readonly { 62 entry: 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 75 define 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 84 define 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 108 define 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 122 define 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 136 define 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 154 define 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 171 define 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. 190 define 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 209 define 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 228 define 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 248 declare noalias i8* @_Znam(i64) noredzone 249 250 define noalias i8* @test12(i64 %count) nounwind ssp noredzone { 251 entry: 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 271 declare { i64, i1 } @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone 272 273 define 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 288 define 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 306 define i32 @test15(i32 %x) nounwind { 307 entry: 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 320 define i64 @test16(i64 %x) nounwind uwtable readnone ssp { 321 entry: 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 334 define i16 @test17(i16 %x) nounwind { 335 entry: 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 348 define 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 363 define 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 369 define 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 381 BB: 382 br label %CF 383 384 CF: 385 %Cmp10 = icmp ule i8 undef, undef 386 br i1 %Cmp10, label %CF, label %CF250 387 388 CF250: 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 393 CF242: 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 400 CF244: 401 %B122 = fadd float %Sl59, undef 402 ret void 403 } 404