2016-11-10 05:41:34 +08:00
|
|
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
2014-03-07 18:24:44 +08:00
|
|
|
; RUN: opt -S -instcombine %s | FileCheck %s
|
|
|
|
|
|
|
|
define <1 x i8> @test1(<8 x i8> %in) {
|
2016-11-10 05:41:34 +08:00
|
|
|
; CHECK-LABEL: @test1(
|
|
|
|
; CHECK-NEXT: [[VEC:%.*]] = shufflevector <8 x i8> %in, <8 x i8> undef, <1 x i32> <i32 5>
|
|
|
|
; CHECK-NEXT: ret <1 x i8> [[VEC]]
|
|
|
|
;
|
2014-03-07 18:24:44 +08:00
|
|
|
%val = extractelement <8 x i8> %in, i32 5
|
|
|
|
%vec = insertelement <1 x i8> undef, i8 %val, i32 0
|
|
|
|
ret <1 x i8> %vec
|
|
|
|
}
|
|
|
|
|
|
|
|
define <4 x i16> @test2(<8 x i16> %in, <8 x i16> %in2) {
|
2016-11-10 05:41:34 +08:00
|
|
|
; CHECK-LABEL: @test2(
|
|
|
|
; CHECK-NEXT: [[VEC_3:%.*]] = shufflevector <8 x i16> %in2, <8 x i16> %in, <4 x i32> <i32 11, i32 9, i32 0, i32 10>
|
|
|
|
; CHECK-NEXT: ret <4 x i16> [[VEC_3]]
|
|
|
|
;
|
2014-03-07 18:24:44 +08:00
|
|
|
%elt0 = extractelement <8 x i16> %in, i32 3
|
|
|
|
%elt1 = extractelement <8 x i16> %in, i32 1
|
|
|
|
%elt2 = extractelement <8 x i16> %in2, i32 0
|
|
|
|
%elt3 = extractelement <8 x i16> %in, i32 2
|
|
|
|
|
|
|
|
%vec.0 = insertelement <4 x i16> undef, i16 %elt0, i32 0
|
|
|
|
%vec.1 = insertelement <4 x i16> %vec.0, i16 %elt1, i32 1
|
|
|
|
%vec.2 = insertelement <4 x i16> %vec.1, i16 %elt2, i32 2
|
|
|
|
%vec.3 = insertelement <4 x i16> %vec.2, i16 %elt3, i32 3
|
|
|
|
|
|
|
|
ret <4 x i16> %vec.3
|
|
|
|
}
|
|
|
|
|
2015-12-01 06:39:36 +08:00
|
|
|
define <2 x i64> @test_vcopyq_lane_p64(<2 x i64> %a, <1 x i64> %b) {
|
2016-11-10 05:41:34 +08:00
|
|
|
; CHECK-LABEL: @test_vcopyq_lane_p64(
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <1 x i64> %b, <1 x i64> undef, <2 x i32> <i32 0, i32 undef>
|
|
|
|
; CHECK-NEXT: [[RES:%.*]] = shufflevector <2 x i64> %a, <2 x i64> [[TMP1]], <2 x i32> <i32 0, i32 2>
|
|
|
|
; CHECK-NEXT: ret <2 x i64> [[RES]]
|
|
|
|
;
|
2014-03-07 18:24:44 +08:00
|
|
|
%elt = extractelement <1 x i64> %b, i32 0
|
|
|
|
%res = insertelement <2 x i64> %a, i64 %elt, i32 1
|
|
|
|
ret <2 x i64> %res
|
|
|
|
}
|
|
|
|
|
2015-12-01 06:39:36 +08:00
|
|
|
; PR2109: https://llvm.org/bugs/show_bug.cgi?id=2109
|
|
|
|
|
|
|
|
define <4 x float> @widen_extract2(<4 x float> %ins, <2 x float> %ext) {
|
|
|
|
; CHECK-LABEL: @widen_extract2(
|
2016-11-10 05:41:34 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x float> %ext, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
|
|
|
|
; CHECK-NEXT: [[I2:%.*]] = shufflevector <4 x float> %ins, <4 x float> [[TMP1]], <4 x i32> <i32 0, i32 4, i32 2, i32 5>
|
|
|
|
; CHECK-NEXT: ret <4 x float> [[I2]]
|
|
|
|
;
|
2015-12-01 06:39:36 +08:00
|
|
|
%e1 = extractelement <2 x float> %ext, i32 0
|
|
|
|
%e2 = extractelement <2 x float> %ext, i32 1
|
|
|
|
%i1 = insertelement <4 x float> %ins, float %e1, i32 1
|
|
|
|
%i2 = insertelement <4 x float> %i1, float %e2, i32 3
|
|
|
|
ret <4 x float> %i2
|
|
|
|
}
|
|
|
|
|
|
|
|
define <4 x float> @widen_extract3(<4 x float> %ins, <3 x float> %ext) {
|
|
|
|
; CHECK-LABEL: @widen_extract3(
|
2016-11-10 05:41:34 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <3 x float> %ext, <3 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
|
|
|
|
; CHECK-NEXT: [[I3:%.*]] = shufflevector <4 x float> %ins, <4 x float> [[TMP1]], <4 x i32> <i32 6, i32 5, i32 4, i32 3>
|
|
|
|
; CHECK-NEXT: ret <4 x float> [[I3]]
|
|
|
|
;
|
2015-12-01 06:39:36 +08:00
|
|
|
%e1 = extractelement <3 x float> %ext, i32 0
|
|
|
|
%e2 = extractelement <3 x float> %ext, i32 1
|
|
|
|
%e3 = extractelement <3 x float> %ext, i32 2
|
|
|
|
%i1 = insertelement <4 x float> %ins, float %e1, i32 2
|
|
|
|
%i2 = insertelement <4 x float> %i1, float %e2, i32 1
|
|
|
|
%i3 = insertelement <4 x float> %i2, float %e3, i32 0
|
|
|
|
ret <4 x float> %i3
|
|
|
|
}
|
|
|
|
|
[InstCombine] transform more extract/insert pairs into shuffles (PR2109)
This is an extension of the shuffle combining from r203229:
http://reviews.llvm.org/rL203229
The idea is to widen a short input vector with undef elements so the
existing shuffle transform for extract/insert can kick in.
The motivation is to finally solve PR2109:
https://llvm.org/bugs/show_bug.cgi?id=2109
For that example, the IR becomes:
%1 = bitcast <2 x i32>* %P to <2 x float>*
%ld1 = load <2 x float>, <2 x float>* %1, align 8
%2 = shufflevector <2 x float> %ld1, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
%i2 = shufflevector <4 x float> %A, <4 x float> %2, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
ret <4 x float> %i2
And x86 SSE output improves from:
movq (%rdi), %xmm1 ## xmm1 = mem[0],zero
movdqa %xmm1, %xmm2
shufps $229, %xmm2, %xmm2 ## xmm2 = xmm2[1,1,2,3]
shufps $48, %xmm0, %xmm1 ## xmm1 = xmm1[0,0],xmm0[3,0]
shufps $132, %xmm1, %xmm0 ## xmm0 = xmm0[0,1],xmm1[0,2]
shufps $32, %xmm0, %xmm2 ## xmm2 = xmm2[0,0],xmm0[2,0]
shufps $36, %xmm2, %xmm0 ## xmm0 = xmm0[0,1],xmm2[2,0]
retq
To the almost optimal:
movhpd (%rdi), %xmm0
Note: There's a tension in the existing transform related to generating
arbitrary shufflevector masks. We avoid that in other places in InstCombine
because we're scared that codegen can't handle strange masks, but it looks
like we're ok with producing those here. I purposely chose weird insert/extract
indexes for the regression tests to see the effect in these cases.
For PowerPC+Altivec, AArch64, and X86+SSE/AVX, I think the codegen is equal or
better for these examples.
Differential Revision: http://reviews.llvm.org/D15096
llvm-svn: 256394
2015-12-25 05:17:56 +08:00
|
|
|
define <8 x float> @widen_extract4(<8 x float> %ins, <2 x float> %ext) {
|
|
|
|
; CHECK-LABEL: @widen_extract4(
|
2016-11-10 05:41:34 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = 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>
|
|
|
|
; CHECK-NEXT: [[I1:%.*]] = shufflevector <8 x float> %ins, <8 x float> [[TMP1]], <8 x i32> <i32 0, i32 1, i32 8, i32 3, i32 4, i32 5, i32 6, i32 7>
|
|
|
|
; CHECK-NEXT: ret <8 x float> [[I1]]
|
|
|
|
;
|
2015-12-01 06:39:36 +08:00
|
|
|
%e1 = extractelement <2 x float> %ext, i32 0
|
|
|
|
%i1 = insertelement <8 x float> %ins, float %e1, i32 2
|
|
|
|
ret <8 x float> %i1
|
|
|
|
}
|
|
|
|
|
2016-01-06 03:09:47 +08:00
|
|
|
; PR26015: https://llvm.org/bugs/show_bug.cgi?id=26015
|
|
|
|
; The widening shuffle must be inserted before any uses.
|
|
|
|
|
|
|
|
define <8 x i16> @pr26015(<4 x i16> %t0) {
|
|
|
|
; CHECK-LABEL: @pr26015(
|
[InstCombine] canonicalize insertelement of scalar constant ahead of insertelement of variable
insertelement (insertelement X, Y, IdxC1), ScalarC, IdxC2 -->
insertelement (insertelement X, ScalarC, IdxC2), Y, IdxC1
As noted in the code comment and seen in the test changes, the motivation is that by pulling
constant insertion up, we may be able to constant fold some insertelement instructions.
Differential Revision: https://reviews.llvm.org/D31196
llvm-svn: 298520
2017-03-23 01:10:44 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i16> %t0, <4 x i16> undef, <8 x i32> <i32 undef, i32 undef, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
|
|
|
|
; CHECK-NEXT: [[T5:%.*]] = shufflevector <8 x i16> <i16 0, i16 0, i16 0, i16 undef, i16 0, i16 0, i16 0, i16 undef>, <8 x i16> [[TMP1]], <8 x i32> <i32 0, i32 1, i32 2, i32 10, i32 4, i32 5, i32 6, i32 11>
|
2016-11-10 05:41:34 +08:00
|
|
|
; CHECK-NEXT: ret <8 x i16> [[T5]]
|
|
|
|
;
|
2016-01-06 03:09:47 +08:00
|
|
|
%t1 = extractelement <4 x i16> %t0, i32 2
|
|
|
|
%t2 = insertelement <8 x i16> zeroinitializer, i16 %t1, i32 3
|
|
|
|
%t3 = insertelement <8 x i16> %t2, i16 0, i32 6
|
|
|
|
%t4 = extractelement <4 x i16> %t0, i32 3
|
|
|
|
%t5 = insertelement <8 x i16> %t3, i16 %t4, i32 7
|
|
|
|
ret <8 x i16> %t5
|
|
|
|
}
|
|
|
|
|
|
|
|
; PR25999: https://llvm.org/bugs/show_bug.cgi?id=25999
|
|
|
|
; TODO: The widening shuffle could be inserted at the start of the function to allow the first extract to use it.
|
|
|
|
|
|
|
|
define <8 x i16> @pr25999(<4 x i16> %t0, i1 %b) {
|
|
|
|
; CHECK-LABEL: @pr25999(
|
2016-11-10 05:41:34 +08:00
|
|
|
; CHECK-NEXT: [[T1:%.*]] = extractelement <4 x i16> %t0, i32 2
|
|
|
|
; CHECK-NEXT: br i1 %b, label %if, label %end
|
2016-01-06 03:09:47 +08:00
|
|
|
; CHECK: if:
|
2016-11-10 05:41:34 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = 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>
|
[InstCombine] canonicalize insertelement of scalar constant ahead of insertelement of variable
insertelement (insertelement X, Y, IdxC1), ScalarC, IdxC2 -->
insertelement (insertelement X, ScalarC, IdxC2), Y, IdxC1
As noted in the code comment and seen in the test changes, the motivation is that by pulling
constant insertion up, we may be able to constant fold some insertelement instructions.
Differential Revision: https://reviews.llvm.org/D31196
llvm-svn: 298520
2017-03-23 01:10:44 +08:00
|
|
|
; CHECK-NEXT: [[T3:%.*]] = insertelement <8 x i16> <i16 0, i16 0, i16 0, i16 undef, i16 0, i16 0, i16 0, i16 undef>, i16 [[T1]], i32 3
|
2016-11-10 05:41:34 +08:00
|
|
|
; CHECK-NEXT: [[T5:%.*]] = shufflevector <8 x i16> [[T3]], <8 x i16> [[TMP1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 11>
|
|
|
|
; CHECK-NEXT: ret <8 x i16> [[T5]]
|
2016-01-06 03:09:47 +08:00
|
|
|
; CHECK: end:
|
2016-11-10 05:41:34 +08:00
|
|
|
; CHECK-NEXT: [[A1:%.*]] = add i16 [[T1]], 4
|
|
|
|
; 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
|
|
|
|
; CHECK-NEXT: ret <8 x i16> [[T6]]
|
|
|
|
;
|
2016-01-06 03:09:47 +08:00
|
|
|
|
|
|
|
%t1 = extractelement <4 x i16> %t0, i32 2
|
|
|
|
br i1 %b, label %if, label %end
|
|
|
|
|
|
|
|
if:
|
|
|
|
%t2 = insertelement <8 x i16> zeroinitializer, i16 %t1, i32 3
|
|
|
|
%t3 = insertelement <8 x i16> %t2, i16 0, i32 6
|
|
|
|
%t4 = extractelement <4 x i16> %t0, i32 3
|
|
|
|
%t5 = insertelement <8 x i16> %t3, i16 %t4, i32 7
|
|
|
|
ret <8 x i16> %t5
|
|
|
|
|
|
|
|
end:
|
|
|
|
%a1 = add i16 %t1, 4
|
|
|
|
%t6 = insertelement <8 x i16> zeroinitializer, i16 %a1, i32 0
|
|
|
|
ret <8 x i16> %t6
|
|
|
|
}
|
|
|
|
|
2016-11-10 05:41:34 +08:00
|
|
|
; The widening shuffle must be inserted at a valid point (after the PHIs).
|
2016-01-08 09:39:16 +08:00
|
|
|
|
|
|
|
define <4 x double> @pr25999_phis1(i1 %c, <2 x double> %a, <4 x double> %b) {
|
|
|
|
; CHECK-LABEL: @pr25999_phis1(
|
2016-11-10 05:41:34 +08:00
|
|
|
; CHECK-NEXT: bb1:
|
|
|
|
; CHECK-NEXT: br i1 %c, label %bb2, label %bb3
|
|
|
|
; CHECK: bb2:
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = call <2 x double> @dummy(<2 x double> %a)
|
|
|
|
; CHECK-NEXT: br label %bb3
|
|
|
|
; CHECK: bb3:
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = phi <2 x double> [ %a, %bb1 ], [ [[R]], %bb2 ]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = shufflevector <2 x double> [[TMP1]], <2 x double> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>
|
|
|
|
; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <4 x double> [[TMP2]], <4 x double> [[TMP0]], <4 x i32> <i32 0, i32 1, i32 4, i32 3>
|
|
|
|
; CHECK-NEXT: ret <4 x double> [[TMP4]]
|
|
|
|
;
|
2016-01-08 09:39:16 +08:00
|
|
|
bb1:
|
|
|
|
br i1 %c, label %bb2, label %bb3
|
|
|
|
|
|
|
|
bb2:
|
|
|
|
%r = call <2 x double> @dummy(<2 x double> %a)
|
|
|
|
br label %bb3
|
|
|
|
|
|
|
|
bb3:
|
|
|
|
%tmp1 = phi <2 x double> [ %a, %bb1 ], [ %r, %bb2 ]
|
|
|
|
%tmp2 = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]
|
|
|
|
%tmp3 = extractelement <2 x double> %tmp1, i32 0
|
|
|
|
%tmp4 = insertelement <4 x double> %tmp2, double %tmp3, i32 2
|
|
|
|
ret <4 x double> %tmp4
|
|
|
|
}
|
|
|
|
|
|
|
|
declare <2 x double> @dummy(<2 x double>)
|
|
|
|
|
|
|
|
define <4 x double> @pr25999_phis2(i1 %c, <2 x double> %a, <4 x double> %b) {
|
|
|
|
; CHECK-LABEL: @pr25999_phis2(
|
2016-11-10 05:41:34 +08:00
|
|
|
; CHECK-NEXT: bb1:
|
|
|
|
; CHECK-NEXT: br i1 %c, label %bb2, label %bb3
|
|
|
|
; CHECK: bb2:
|
|
|
|
; CHECK-NEXT: [[R:%.*]] = call <2 x double> @dummy(<2 x double> %a)
|
|
|
|
; CHECK-NEXT: br label %bb3
|
|
|
|
; CHECK: bb3:
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = phi <2 x double> [ %a, %bb1 ], [ [[R]], %bb2 ]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]
|
|
|
|
; CHECK-NEXT: [[D:%.*]] = fadd <2 x double> [[TMP1]], [[TMP1]]
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = shufflevector <2 x double> [[D]], <2 x double> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>
|
|
|
|
; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <4 x double> [[TMP2]], <4 x double> [[TMP0]], <4 x i32> <i32 0, i32 1, i32 4, i32 3>
|
|
|
|
; CHECK-NEXT: ret <4 x double> [[TMP4]]
|
|
|
|
;
|
2016-01-08 09:39:16 +08:00
|
|
|
bb1:
|
|
|
|
br i1 %c, label %bb2, label %bb3
|
|
|
|
|
|
|
|
bb2:
|
|
|
|
%r = call <2 x double> @dummy(<2 x double> %a)
|
|
|
|
br label %bb3
|
|
|
|
|
|
|
|
bb3:
|
|
|
|
%tmp1 = phi <2 x double> [ %a, %bb1 ], [ %r, %bb2 ]
|
|
|
|
%tmp2 = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]
|
|
|
|
%d = fadd <2 x double> %tmp1, %tmp1
|
|
|
|
%tmp3 = extractelement <2 x double> %d, i32 0
|
|
|
|
%tmp4 = insertelement <4 x double> %tmp2, double %tmp3, i32 2
|
|
|
|
ret <4 x double> %tmp4
|
|
|
|
}
|
|
|
|
|
2016-01-30 04:21:02 +08:00
|
|
|
; PR26354: https://llvm.org/bugs/show_bug.cgi?id=26354
|
|
|
|
; Don't create a shufflevector if we know that we're not going to replace the insertelement.
|
|
|
|
|
|
|
|
define double @pr26354(<2 x double>* %tmp, i1 %B) {
|
|
|
|
; CHECK-LABEL: @pr26354(
|
2016-11-10 05:41:34 +08:00
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[LD:%.*]] = load <2 x double>, <2 x double>* %tmp, align 16
|
|
|
|
; CHECK-NEXT: [[E1:%.*]] = extractelement <2 x double> [[LD]], i32 0
|
|
|
|
; CHECK-NEXT: br i1 %B, label %if, label %end
|
2016-01-30 04:21:02 +08:00
|
|
|
; CHECK: if:
|
2016-11-10 05:41:34 +08:00
|
|
|
; CHECK-NEXT: [[E2:%.*]] = extractelement <2 x double> [[LD]], i32 1
|
|
|
|
; CHECK-NEXT: [[I1:%.*]] = insertelement <4 x double> <double 0.000000e+00, double 0.000000e+00, double 0.000000e+00, double undef>, double [[E2]], i32 3
|
|
|
|
; CHECK-NEXT: br label %end
|
|
|
|
; CHECK: end:
|
|
|
|
; CHECK-NEXT: [[PH:%.*]] = phi <4 x double> [ undef, %entry ], [ [[I1]], %if ]
|
|
|
|
; CHECK-NEXT: [[E3:%.*]] = extractelement <4 x double> [[PH]], i32 1
|
|
|
|
; CHECK-NEXT: [[MU:%.*]] = fmul double [[E1]], [[E3]]
|
|
|
|
; CHECK-NEXT: ret double [[MU]]
|
|
|
|
;
|
2016-01-30 04:21:02 +08:00
|
|
|
|
|
|
|
entry:
|
|
|
|
%ld = load <2 x double>, <2 x double>* %tmp
|
|
|
|
%e1 = extractelement <2 x double> %ld, i32 0
|
|
|
|
%e2 = extractelement <2 x double> %ld, i32 1
|
|
|
|
br i1 %B, label %if, label %end
|
|
|
|
|
|
|
|
if:
|
|
|
|
%i1 = insertelement <4 x double> zeroinitializer, double %e2, i32 3
|
|
|
|
br label %end
|
|
|
|
|
|
|
|
end:
|
|
|
|
%ph = phi <4 x double> [ undef, %entry ], [ %i1, %if ]
|
|
|
|
%e3 = extractelement <4 x double> %ph, i32 1
|
|
|
|
%mu = fmul double %e1, %e3
|
|
|
|
ret double %mu
|
|
|
|
}
|
|
|
|
|
2016-11-10 08:15:14 +08:00
|
|
|
; https://llvm.org/bugs/show_bug.cgi?id=30923
|
|
|
|
; Delete the widening shuffle if we're not going to reduce the extract/insert to a shuffle.
|
|
|
|
|
|
|
|
define <4 x float> @PR30923(<2 x float> %x) {
|
|
|
|
; CHECK-LABEL: @PR30923(
|
|
|
|
; CHECK-NEXT: bb1:
|
|
|
|
; CHECK-NEXT: [[EXT1:%.*]] = extractelement <2 x float> %x, i32 1
|
|
|
|
; CHECK-NEXT: store float [[EXT1]], float* undef, align 4
|
|
|
|
; CHECK-NEXT: br label %bb2
|
|
|
|
; CHECK: bb2:
|
|
|
|
; CHECK-NEXT: [[EXT2:%.*]] = extractelement <2 x float> %x, i32 0
|
|
|
|
; CHECK-NEXT: [[INS1:%.*]] = insertelement <4 x float> <float 0.000000e+00, float 0.000000e+00, float undef, float undef>, float [[EXT2]], i32 2
|
|
|
|
; CHECK-NEXT: [[INS2:%.*]] = insertelement <4 x float> [[INS1]], float [[EXT1]], i32 3
|
|
|
|
; CHECK-NEXT: ret <4 x float> [[INS2]]
|
|
|
|
;
|
|
|
|
bb1:
|
|
|
|
%ext1 = extractelement <2 x float> %x, i32 1
|
|
|
|
store float %ext1, float* undef, align 4
|
|
|
|
br label %bb2
|
|
|
|
|
|
|
|
bb2:
|
|
|
|
%widen = shufflevector <2 x float> %x, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
|
|
|
|
%ext2 = extractelement <4 x float> %widen, i32 0
|
|
|
|
%ins1 = insertelement <4 x float> <float 0.0, float 0.0, float undef, float undef>, float %ext2, i32 2
|
|
|
|
%ins2 = insertelement <4 x float> %ins1, float %ext1, i32 3
|
|
|
|
ret <4 x float> %ins2
|
|
|
|
}
|
2017-06-05 17:18:10 +08:00
|
|
|
|
|
|
|
; Don't insert extractelements from the wider vector before the def of the index operand.
|
|
|
|
|
|
|
|
define <4 x i32> @extractelt_insertion(<2 x i32> %x, i32 %y) {
|
|
|
|
; CHECK-LABEL: @extractelt_insertion(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
|
|
|
|
; CHECK-NEXT: [[B:%.*]] = shufflevector <4 x i32> <i32 0, i32 0, i32 0, i32 undef>, <4 x i32> [[TMP0]], <4 x i32> <i32 0, i32 1, i32 2, i32 5>
|
|
|
|
; CHECK-NEXT: [[C:%.*]] = add i32 [[Y:%.*]], 3
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x i32> [[TMP0]], i32 [[C]]
|
|
|
|
; CHECK-NEXT: [[E:%.*]] = icmp eq i32 [[TMP1]], 0
|
|
|
|
; CHECK-NEXT: [[RET:%.*]] = select i1 [[E]], <4 x i32> [[B]], <4 x i32> zeroinitializer
|
|
|
|
; CHECK-NEXT: ret <4 x i32> [[RET]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%a = extractelement <2 x i32> %x, i32 1
|
|
|
|
%b = insertelement <4 x i32> zeroinitializer, i32 %a, i64 3
|
|
|
|
%c = add i32 %y, 3
|
|
|
|
%d = extractelement <2 x i32> %x, i32 %c
|
|
|
|
%e = icmp eq i32 %d, 0
|
|
|
|
%ret = select i1 %e, <4 x i32> %b, <4 x i32> zeroinitializer
|
|
|
|
ret <4 x i32> %ret
|
|
|
|
}
|