Home | History | Annotate | Download | only in X86
      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