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* %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
     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: test2:
     37 ; CHECK: movnew
     38 ; CHECK: movswl
     39 
     40 ; ATOM: test2:
     41 ; ATOM: movnew
     42 ; ATOM: movswl
     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: test3:
     55 ; CHECK: movss	{{.*}},4), %xmm0
     56 
     57 ; ATOM: 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* %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 
     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: test5:
     80 
     81 ; ATOM: test5:
     82 }
     83 
     84 define 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
    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: 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
    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: test8:
    129 
    130 ; ATOM: 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: 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
    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: 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 
    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: 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.
    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: 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 
    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: 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 
    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: 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 
    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: 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 
    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: 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-NEXT: 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: 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-NEXT: 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: test15:
    312 ; CHECK: negl
    313 ; CHECK: sbbl
    314 
    315 ; ATOM: 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: test16:
    326 ; CHECK: negq
    327 ; CHECK: sbbq
    328 
    329 ; ATOM: 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: test17:
    340 ; CHECK: negw
    341 ; CHECK: sbbw
    342 
    343 ; ATOM: test17:
    344 ; ATOM: negw
    345 ; ATOM: sbbw
    346 }
    347