Home | History | Annotate | Download | only in X86
      1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
      2 ; RUN: llc < %s -o - -mcpu=generic -mtriple=x86_64-apple-darwin -mattr=+sse2 | FileCheck %s --check-prefixes=CHECK,SSE2
      3 ; RUN: llc < %s -o - -mcpu=generic -mtriple=x86_64-apple-darwin -mattr=+sse4.2 | FileCheck %s --check-prefixes=CHECK,SSE41
      4 
      5 ; For a setult against a constant, turn it into a setule and lower via psubusw.
      6 
      7 define void @loop_no_const_reload(<2 x i64>*  %in, <2 x i64>* %out, i32 %n) {
      8 ; SSE2-LABEL: loop_no_const_reload:
      9 ; SSE2:       ## %bb.0: ## %entry
     10 ; SSE2-NEXT:    testl %edx, %edx
     11 ; SSE2-NEXT:    je LBB0_3
     12 ; SSE2-NEXT:  ## %bb.1: ## %for.body.preheader
     13 ; SSE2-NEXT:    xorl %eax, %eax
     14 ; SSE2-NEXT:    movdqa {{.*#+}} xmm0 = [25,25,25,25,25,25,25,25]
     15 ; SSE2-NEXT:    pxor %xmm1, %xmm1
     16 ; SSE2-NEXT:    .p2align 4, 0x90
     17 ; SSE2-NEXT:  LBB0_2: ## %for.body
     18 ; SSE2-NEXT:    ## =>This Inner Loop Header: Depth=1
     19 ; SSE2-NEXT:    movdqa (%rdi,%rax), %xmm2
     20 ; SSE2-NEXT:    psubusw %xmm0, %xmm2
     21 ; SSE2-NEXT:    pcmpeqw %xmm1, %xmm2
     22 ; SSE2-NEXT:    movdqa %xmm2, (%rsi,%rax)
     23 ; SSE2-NEXT:    addq $16, %rax
     24 ; SSE2-NEXT:    decl %edx
     25 ; SSE2-NEXT:    jne LBB0_2
     26 ; SSE2-NEXT:  LBB0_3: ## %for.end
     27 ; SSE2-NEXT:    retq
     28 ;
     29 ; SSE41-LABEL: loop_no_const_reload:
     30 ; SSE41:       ## %bb.0: ## %entry
     31 ; SSE41-NEXT:    testl %edx, %edx
     32 ; SSE41-NEXT:    je LBB0_3
     33 ; SSE41-NEXT:  ## %bb.1: ## %for.body.preheader
     34 ; SSE41-NEXT:    xorl %eax, %eax
     35 ; SSE41-NEXT:    movdqa {{.*#+}} xmm0 = [26,26,26,26,26,26,26,26]
     36 ; SSE41-NEXT:    pcmpeqd %xmm1, %xmm1
     37 ; SSE41-NEXT:    .p2align 4, 0x90
     38 ; SSE41-NEXT:  LBB0_2: ## %for.body
     39 ; SSE41-NEXT:    ## =>This Inner Loop Header: Depth=1
     40 ; SSE41-NEXT:    movdqa (%rdi,%rax), %xmm2
     41 ; SSE41-NEXT:    movdqa %xmm2, %xmm3
     42 ; SSE41-NEXT:    pmaxuw %xmm0, %xmm3
     43 ; SSE41-NEXT:    pcmpeqw %xmm2, %xmm3
     44 ; SSE41-NEXT:    pxor %xmm1, %xmm3
     45 ; SSE41-NEXT:    movdqa %xmm3, (%rsi,%rax)
     46 ; SSE41-NEXT:    addq $16, %rax
     47 ; SSE41-NEXT:    decl %edx
     48 ; SSE41-NEXT:    jne LBB0_2
     49 ; SSE41-NEXT:  LBB0_3: ## %for.end
     50 ; SSE41-NEXT:    retq
     51 entry:
     52   %cmp9 = icmp eq i32 %n, 0
     53   br i1 %cmp9, label %for.end, label %for.body
     54 
     55 for.body:                                         ; preds = %for.body, %entry
     56   %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
     57   %arrayidx1 = getelementptr inbounds <2 x i64>, <2 x i64>* %in, i64 %indvars.iv
     58   %arrayidx1.val = load <2 x i64>, <2 x i64>* %arrayidx1, align 16
     59   %0 = bitcast <2 x i64> %arrayidx1.val to <8 x i16>
     60   %cmp.i.i = icmp ult <8 x i16> %0, <i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26>
     61   %sext.i.i = sext <8 x i1> %cmp.i.i to <8 x i16>
     62   %1 = bitcast <8 x i16> %sext.i.i to <2 x i64>
     63   %arrayidx5 = getelementptr inbounds <2 x i64>, <2 x i64>* %out, i64 %indvars.iv
     64   store <2 x i64> %1, <2 x i64>* %arrayidx5, align 16
     65   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
     66   %lftr.wideiv = trunc i64 %indvars.iv.next to i32
     67   %exitcond = icmp eq i32 %lftr.wideiv, %n
     68   br i1 %exitcond, label %for.end, label %for.body
     69 
     70 for.end:                                          ; preds = %for.body, %entry
     71   ret void
     72 }
     73 
     74 ; Be careful if decrementing the constant would undeflow.
     75 
     76 define void @loop_const_folding_underflow(<2 x i64>*  %in, <2 x i64>* %out, i32 %n) {
     77 ; SSE2-LABEL: loop_const_folding_underflow:
     78 ; SSE2:       ## %bb.0: ## %entry
     79 ; SSE2-NEXT:    testl %edx, %edx
     80 ; SSE2-NEXT:    je LBB1_3
     81 ; SSE2-NEXT:  ## %bb.1: ## %for.body.preheader
     82 ; SSE2-NEXT:    xorl %eax, %eax
     83 ; SSE2-NEXT:    movdqa {{.*#+}} xmm0 = [32768,32768,32768,32768,32768,32768,32768,32768]
     84 ; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [32768,32794,32794,32794,32794,32794,32794,32794]
     85 ; SSE2-NEXT:    .p2align 4, 0x90
     86 ; SSE2-NEXT:  LBB1_2: ## %for.body
     87 ; SSE2-NEXT:    ## =>This Inner Loop Header: Depth=1
     88 ; SSE2-NEXT:    movdqa (%rdi,%rax), %xmm2
     89 ; SSE2-NEXT:    pxor %xmm0, %xmm2
     90 ; SSE2-NEXT:    movdqa %xmm1, %xmm3
     91 ; SSE2-NEXT:    pcmpgtw %xmm2, %xmm3
     92 ; SSE2-NEXT:    movdqa %xmm3, (%rsi,%rax)
     93 ; SSE2-NEXT:    addq $16, %rax
     94 ; SSE2-NEXT:    decl %edx
     95 ; SSE2-NEXT:    jne LBB1_2
     96 ; SSE2-NEXT:  LBB1_3: ## %for.end
     97 ; SSE2-NEXT:    retq
     98 ;
     99 ; SSE41-LABEL: loop_const_folding_underflow:
    100 ; SSE41:       ## %bb.0: ## %entry
    101 ; SSE41-NEXT:    testl %edx, %edx
    102 ; SSE41-NEXT:    je LBB1_3
    103 ; SSE41-NEXT:  ## %bb.1: ## %for.body.preheader
    104 ; SSE41-NEXT:    xorl %eax, %eax
    105 ; SSE41-NEXT:    movdqa {{.*#+}} xmm0 = [0,26,26,26,26,26,26,26]
    106 ; SSE41-NEXT:    pcmpeqd %xmm1, %xmm1
    107 ; SSE41-NEXT:    .p2align 4, 0x90
    108 ; SSE41-NEXT:  LBB1_2: ## %for.body
    109 ; SSE41-NEXT:    ## =>This Inner Loop Header: Depth=1
    110 ; SSE41-NEXT:    movdqa (%rdi,%rax), %xmm2
    111 ; SSE41-NEXT:    movdqa %xmm2, %xmm3
    112 ; SSE41-NEXT:    pmaxuw %xmm0, %xmm3
    113 ; SSE41-NEXT:    pcmpeqw %xmm2, %xmm3
    114 ; SSE41-NEXT:    pxor %xmm1, %xmm3
    115 ; SSE41-NEXT:    movdqa %xmm3, (%rsi,%rax)
    116 ; SSE41-NEXT:    addq $16, %rax
    117 ; SSE41-NEXT:    decl %edx
    118 ; SSE41-NEXT:    jne LBB1_2
    119 ; SSE41-NEXT:  LBB1_3: ## %for.end
    120 ; SSE41-NEXT:    retq
    121 entry:
    122   %cmp9 = icmp eq i32 %n, 0
    123   br i1 %cmp9, label %for.end, label %for.body
    124 
    125 for.body:                                         ; preds = %for.body, %entry
    126   %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
    127   %arrayidx1 = getelementptr inbounds <2 x i64>, <2 x i64>* %in, i64 %indvars.iv
    128   %arrayidx1.val = load <2 x i64>, <2 x i64>* %arrayidx1, align 16
    129   %0 = bitcast <2 x i64> %arrayidx1.val to <8 x i16>
    130   %cmp.i.i = icmp ult <8 x i16> %0, <i16 0, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26>
    131   %sext.i.i = sext <8 x i1> %cmp.i.i to <8 x i16>
    132   %1 = bitcast <8 x i16> %sext.i.i to <2 x i64>
    133   %arrayidx5 = getelementptr inbounds <2 x i64>, <2 x i64>* %out, i64 %indvars.iv
    134   store <2 x i64> %1, <2 x i64>* %arrayidx5, align 16
    135   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
    136   %lftr.wideiv = trunc i64 %indvars.iv.next to i32
    137   %exitcond = icmp eq i32 %lftr.wideiv, %n
    138   br i1 %exitcond, label %for.end, label %for.body
    139 
    140 for.end:                                          ; preds = %for.body, %entry
    141   ret void
    142 }
    143 
    144 ; Test for PSUBUSB
    145 
    146 define <16 x i8> @test_ult_byte(<16 x i8> %a) {
    147 ; CHECK-LABEL: test_ult_byte:
    148 ; CHECK:       ## %bb.0: ## %entry
    149 ; CHECK-NEXT:    movdqa {{.*#+}} xmm1 = [11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11]
    150 ; CHECK-NEXT:    pmaxub %xmm0, %xmm1
    151 ; CHECK-NEXT:    pcmpeqb %xmm1, %xmm0
    152 ; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
    153 ; CHECK-NEXT:    pxor %xmm1, %xmm0
    154 ; CHECK-NEXT:    retq
    155 entry:
    156   %icmp = icmp ult <16 x i8> %a, <i8 11, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11, i8 11>
    157   %sext = sext <16 x i1> %icmp to <16 x i8>
    158   ret <16 x i8> %sext
    159 }
    160 
    161 ; Only do this when we can turn the comparison into a setule.  I.e. not for
    162 ; register operands.
    163 
    164 define <8 x i16> @test_ult_register(<8 x i16> %a, <8 x i16> %b) {
    165 ; SSE2-LABEL: test_ult_register:
    166 ; SSE2:       ## %bb.0: ## %entry
    167 ; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [32768,32768,32768,32768,32768,32768,32768,32768]
    168 ; SSE2-NEXT:    pxor %xmm2, %xmm0
    169 ; SSE2-NEXT:    pxor %xmm1, %xmm2
    170 ; SSE2-NEXT:    pcmpgtw %xmm0, %xmm2
    171 ; SSE2-NEXT:    movdqa %xmm2, %xmm0
    172 ; SSE2-NEXT:    retq
    173 ;
    174 ; SSE41-LABEL: test_ult_register:
    175 ; SSE41:       ## %bb.0: ## %entry
    176 ; SSE41-NEXT:    pmaxuw %xmm0, %xmm1
    177 ; SSE41-NEXT:    pcmpeqw %xmm1, %xmm0
    178 ; SSE41-NEXT:    pcmpeqd %xmm1, %xmm1
    179 ; SSE41-NEXT:    pxor %xmm1, %xmm0
    180 ; SSE41-NEXT:    retq
    181 entry:
    182   %icmp = icmp ult <8 x i16> %a, %b
    183   %sext = sext <8 x i1> %icmp to <8 x i16>
    184   ret <8 x i16> %sext
    185 }
    186