Home | History | Annotate | Download | only in InstCombine
      1 ; RUN: opt -S -instcombine %s | FileCheck %s
      2 
      3 define <1 x i8> @test1(<8 x i8> %in) {
      4 ; CHECK-LABEL: @test1
      5 ; CHECK: shufflevector <8 x i8> %in, <8 x i8> undef, <1 x i32> <i32 5>
      6   %val = extractelement <8 x i8> %in, i32 5
      7   %vec = insertelement <1 x i8> undef, i8 %val, i32 0
      8   ret <1 x i8> %vec
      9 }
     10 
     11 define <4 x i16> @test2(<8 x i16> %in, <8 x i16> %in2) {
     12 ; CHECK-LABEL: @test2
     13 ; CHECK: shufflevector <8 x i16> %in2, <8 x i16> %in, <4 x i32> <i32 11, i32 9, i32 0, i32 10>
     14   %elt0 = extractelement <8 x i16> %in, i32 3
     15   %elt1 = extractelement <8 x i16> %in, i32 1
     16   %elt2 = extractelement <8 x i16> %in2, i32 0
     17   %elt3 = extractelement <8 x i16> %in, i32 2
     18 
     19   %vec.0 = insertelement <4 x i16> undef, i16 %elt0, i32 0
     20   %vec.1 = insertelement <4 x i16> %vec.0, i16 %elt1, i32 1
     21   %vec.2 = insertelement <4 x i16> %vec.1, i16 %elt2, i32 2
     22   %vec.3 = insertelement <4 x i16> %vec.2, i16 %elt3, i32 3
     23 
     24   ret <4 x i16> %vec.3
     25 }
     26 
     27 define <2 x i64> @test_vcopyq_lane_p64(<2 x i64> %a, <1 x i64> %b) {
     28 ; CHECK-LABEL: @test_vcopyq_lane_p64
     29 ; CHECK-NEXT: %[[WIDEVEC:.*]] = shufflevector <1 x i64> %b, <1 x i64> undef, <2 x i32> <i32 0, i32 undef>
     30 ; CHECK-NEXT: shufflevector <2 x i64> %a, <2 x i64> %[[WIDEVEC]], <2 x i32> <i32 0, i32 2>
     31 ; CHECK-NEXT: ret <2 x i64> %res
     32   %elt = extractelement <1 x i64> %b, i32 0
     33   %res = insertelement <2 x i64> %a, i64 %elt, i32 1
     34   ret <2 x i64> %res
     35 }
     36 
     37 ; PR2109: https://llvm.org/bugs/show_bug.cgi?id=2109
     38 
     39 define <4 x float> @widen_extract2(<4 x float> %ins, <2 x float> %ext) {
     40 ; CHECK-LABEL: @widen_extract2(
     41 ; CHECK-NEXT: %[[WIDEVEC:.*]] = shufflevector <2 x float> %ext, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
     42 ; CHECK-NEXT: shufflevector <4 x float> %ins, <4 x float> %[[WIDEVEC]], <4 x i32> <i32 0, i32 4, i32 2, i32 5>
     43 ; CHECK-NEXT: ret <4 x float> %i2
     44   %e1 = extractelement <2 x float> %ext, i32 0
     45   %e2 = extractelement <2 x float> %ext, i32 1
     46   %i1 = insertelement <4 x float> %ins, float %e1, i32 1
     47   %i2 = insertelement <4 x float> %i1, float %e2, i32 3
     48   ret <4 x float> %i2
     49 }
     50 
     51 define <4 x float> @widen_extract3(<4 x float> %ins, <3 x float> %ext) {
     52 ; CHECK-LABEL: @widen_extract3(
     53 ; CHECK-NEXT: %[[WIDEVEC:.*]] = shufflevector <3 x float> %ext, <3 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
     54 ; CHECK-NEXT: shufflevector <4 x float> %ins, <4 x float> %[[WIDEVEC]], <4 x i32> <i32 6, i32 5, i32 4, i32 3>
     55 ; CHECK-NEXT: ret <4 x float> %i3
     56   %e1 = extractelement <3 x float> %ext, i32 0
     57   %e2 = extractelement <3 x float> %ext, i32 1
     58   %e3 = extractelement <3 x float> %ext, i32 2
     59   %i1 = insertelement <4 x float> %ins, float %e1, i32 2
     60   %i2 = insertelement <4 x float> %i1, float %e2, i32 1
     61   %i3 = insertelement <4 x float> %i2, float %e3, i32 0
     62   ret <4 x float> %i3
     63 }
     64 
     65 define <8 x float> @widen_extract4(<8 x float> %ins, <2 x float> %ext) {
     66 ; CHECK-LABEL: @widen_extract4(
     67 ; CHECK-NEXT: %[[WIDEVEC:.*]] = shufflevector <2 x float> %ext, <2 x float> undef, <8 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
     68 ; CHECK-NEXT: shufflevector <8 x float> %ins, <8 x float> %[[WIDEVEC]], <8 x i32> <i32 0, i32 1, i32 8, i32 3, i32 4, i32 5, i32 6, i32 7>
     69 ; CHECK-NEXT: ret <8 x float> %i1
     70   %e1 = extractelement <2 x float> %ext, i32 0
     71   %i1 = insertelement <8 x float> %ins, float %e1, i32 2
     72   ret <8 x float> %i1
     73 }
     74 
     75 ; PR26015: https://llvm.org/bugs/show_bug.cgi?id=26015
     76 ; The widening shuffle must be inserted before any uses.
     77 
     78 define <8 x i16> @pr26015(<4 x i16> %t0) {
     79 ; CHECK-LABEL: @pr26015(
     80 ; CHECK-NEXT:  %[[WIDEVEC:.*]] = shufflevector <4 x i16> %t0, <4 x i16> undef, <8 x i32> <i32 undef, i32 undef, i32 undef, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
     81 ; CHECK-NEXT:  %[[EXT:.*]] = extractelement <4 x i16> %t0, i32 2
     82 ; CHECK-NEXT:  %t2 = insertelement <8 x i16> <i16 0, i16 0, i16 0, i16 undef, i16 0, i16 0, i16 undef, i16 undef>, i16 %[[EXT]], i32 3
     83 ; CHECK-NEXT:  %t3 = insertelement <8 x i16> %t2, i16 0, i32 6
     84 ; CHECK-NEXT:  %t5 = shufflevector <8 x i16> %t3, <8 x i16> %[[WIDEVEC]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 11>
     85 ; CHECK-NEXT:  ret <8 x i16> %t5
     86   %t1 = extractelement <4 x i16> %t0, i32 2
     87   %t2 = insertelement <8 x i16> zeroinitializer, i16 %t1, i32 3
     88   %t3 = insertelement <8 x i16> %t2, i16 0, i32 6
     89   %t4 = extractelement <4 x i16> %t0, i32 3
     90   %t5 = insertelement <8 x i16> %t3, i16 %t4, i32 7
     91   ret <8 x i16> %t5
     92 }
     93 
     94 ; PR25999: https://llvm.org/bugs/show_bug.cgi?id=25999
     95 ; TODO: The widening shuffle could be inserted at the start of the function to allow the first extract to use it.
     96 
     97 define <8 x i16> @pr25999(<4 x i16> %t0, i1 %b) {
     98 ; CHECK-LABEL: @pr25999(
     99 ; CHECK-NEXT:  %t1 = extractelement <4 x i16> %t0, i32 2
    100 ; CHECK-NEXT:  br i1 %b, label %if, label %end
    101 ; CHECK:       if:
    102 ; CHECK-NEXT:  %[[WIDEVEC:.*]] = shufflevector <4 x i16> %t0, <4 x i16> undef, <8 x i32> <i32 undef, i32 undef, i32 undef, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
    103 ; CHECK-NEXT:  %t2 = insertelement <8 x i16> <i16 0, i16 0, i16 0, i16 undef, i16 0, i16 0, i16 undef, i16 undef>, i16 %t1, i32 3
    104 ; CHECK-NEXT:  %t3 = insertelement <8 x i16> %t2, i16 0, i32 6
    105 ; CHECK-NEXT:  %t5 = shufflevector <8 x i16> %t3, <8 x i16> %[[WIDEVEC]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 11>
    106 ; CHECK-NEXT:  ret <8 x i16> %t5
    107 ; CHECK:       end:
    108 ; CHECK-NEXT:  %a1 = add i16 %t1, 4
    109 ; CHECK-NEXT:  %t6 = insertelement <8 x i16> <i16 undef, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>, i16 %a1, i32 0
    110 ; CHECK-NEXT:  ret <8 x i16> %t6
    111 
    112   %t1 = extractelement <4 x i16> %t0, i32 2
    113   br i1 %b, label %if, label %end
    114 
    115 if:
    116   %t2 = insertelement <8 x i16> zeroinitializer, i16 %t1, i32 3
    117   %t3 = insertelement <8 x i16> %t2, i16 0, i32 6
    118   %t4 = extractelement <4 x i16> %t0, i32 3
    119   %t5 = insertelement <8 x i16> %t3, i16 %t4, i32 7
    120   ret <8 x i16> %t5
    121 
    122 end:
    123   %a1 = add i16 %t1, 4
    124   %t6 = insertelement <8 x i16> zeroinitializer, i16 %a1, i32 0
    125   ret <8 x i16> %t6
    126 }
    127 
    128 ; The widening shuffle must be inserted at a valid point (after the PHIs). 
    129 
    130 define <4 x double> @pr25999_phis1(i1 %c, <2 x double> %a, <4 x double> %b) {
    131 ; CHECK-LABEL: @pr25999_phis1(
    132 ; CHECK:       %tmp1 = phi <2 x double> [ %a, %bb1 ], [ %r, %bb2 ]
    133 ; CHECK-NEXT:  %tmp2 = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]
    134 ; CHECK-NEXT:  %[[WIDEVEC:.*]] = shufflevector <2 x double> %tmp1, <2 x double> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>
    135 ; CHECK-NEXT:  %tmp4 = shufflevector <4 x double> %tmp2, <4 x double> %[[WIDEVEC]], <4 x i32> <i32 0, i32 1, i32 4, i32 3>
    136 ; CHECK-NEXT:  ret <4 x double> %tmp4
    137 bb1:
    138   br i1 %c, label %bb2, label %bb3
    139 
    140 bb2:
    141   %r = call <2 x double> @dummy(<2 x double> %a)
    142   br label %bb3
    143 
    144 bb3:
    145   %tmp1 = phi <2 x double> [ %a, %bb1 ], [ %r, %bb2 ]
    146   %tmp2 = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]
    147   %tmp3 = extractelement <2 x double> %tmp1, i32 0
    148   %tmp4 = insertelement <4 x double> %tmp2, double %tmp3, i32 2
    149   ret <4 x double> %tmp4
    150 }
    151 
    152 declare <2 x double> @dummy(<2 x double>)
    153 
    154 define <4 x double> @pr25999_phis2(i1 %c, <2 x double> %a, <4 x double> %b) {
    155 ; CHECK-LABEL: @pr25999_phis2(
    156 ; CHECK:       %tmp1 = phi <2 x double> [ %a, %bb1 ], [ %r, %bb2 ]
    157 ; CHECK-NEXT:  %tmp2 = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]
    158 ; CHECK-NEXT:  %d = fadd <2 x double> %tmp1, %tmp1
    159 ; CHECK-NEXT:  %[[WIDEVEC:.*]] = shufflevector <2 x double> %d, <2 x double> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>
    160 ; CHECK-NEXT:  %tmp4 = shufflevector <4 x double> %tmp2, <4 x double> %[[WIDEVEC]], <4 x i32> <i32 0, i32 1, i32 4, i32 3>
    161 ; CHECK-NEXT:  ret <4 x double> %tmp4
    162 bb1:
    163   br i1 %c, label %bb2, label %bb3
    164 
    165 bb2:
    166   %r = call <2 x double> @dummy(<2 x double> %a)
    167   br label %bb3
    168 
    169 bb3:
    170   %tmp1 = phi <2 x double> [ %a, %bb1 ], [ %r, %bb2 ]
    171   %tmp2 = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]
    172   %d = fadd <2 x double> %tmp1, %tmp1
    173   %tmp3 = extractelement <2 x double> %d, i32 0
    174   %tmp4 = insertelement <4 x double> %tmp2, double %tmp3, i32 2
    175   ret <4 x double> %tmp4
    176 }
    177 
    178 ; PR26354: https://llvm.org/bugs/show_bug.cgi?id=26354
    179 ; Don't create a shufflevector if we know that we're not going to replace the insertelement.
    180 
    181 define double @pr26354(<2 x double>* %tmp, i1 %B) {
    182 ; CHECK-LABEL: @pr26354(
    183 ; CHECK:       %ld = load <2 x double>, <2 x double>* %tmp
    184 ; CHECK-NEXT:  %e1 = extractelement <2 x double> %ld, i32 0
    185 ; CHECK-NEXT:  br i1 %B, label %if, label %end
    186 ; CHECK:       if:
    187 ; CHECK-NEXT:  %e2 = extractelement <2 x double> %ld, i32 1
    188 ; CHECK-NEXT:  %i1 = insertelement <4 x double>
    189 ; CHECK-NEXT:  br label %end
    190 
    191 entry:
    192   %ld = load <2 x double>, <2 x double>* %tmp
    193   %e1 = extractelement <2 x double> %ld, i32 0
    194   %e2 = extractelement <2 x double> %ld, i32 1
    195   br i1 %B, label %if, label %end
    196 
    197 if:
    198   %i1 = insertelement <4 x double> zeroinitializer, double %e2, i32 3
    199   br label %end
    200 
    201 end:
    202   %ph = phi <4 x double> [ undef, %entry ], [ %i1, %if ]
    203   %e3 = extractelement <4 x double> %ph, i32 1
    204   %mu = fmul double %e1, %e3
    205   ret double %mu
    206 }
    207 
    208