2014-03-18 22:07:45 +00:00
|
|
|
Pull in r203311 from upstream llvm trunk (by Arnold Schwaighofer):
|
|
|
|
|
|
|
|
ISel: Make VSELECT selection terminate in cases where the condition type has to
|
|
|
|
be split and the result type widened.
|
|
|
|
|
|
|
|
When the condition of a vselect has to be split it makes no sense widening the
|
|
|
|
vselect and thereby widening the condition. We end up in an endless loop of
|
|
|
|
widening (vselect result type) and splitting (condition mask type) doing this.
|
|
|
|
Instead, split both the condition and the vselect and widen the result.
|
|
|
|
|
|
|
|
I ran this over the test suite with i686 and mattr=+sse and saw no regressions.
|
|
|
|
|
|
|
|
Fixes PR18036.
|
|
|
|
|
2014-05-24 22:27:31 +00:00
|
|
|
Introduced here: http://svnweb.freebsd.org/changeset/base/263313
|
2014-03-18 22:07:45 +00:00
|
|
|
|
|
|
|
Index: test/CodeGen/X86/sse1.ll
|
|
|
|
===================================================================
|
|
|
|
--- test/CodeGen/X86/sse1.ll
|
|
|
|
+++ test/CodeGen/X86/sse1.ll
|
|
|
|
@@ -43,3 +43,17 @@ entry:
|
|
|
|
; CHECK-NOT: shufps $16
|
|
|
|
; CHECK: ret
|
|
|
|
}
|
|
|
|
+
|
|
|
|
+; We used to get stuck in type legalization for this example when lowering the
|
|
|
|
+; vselect. With SSE1 v4f32 is a legal type but v4i1 (or any vector integer type)
|
|
|
|
+; is not. We used to ping pong between splitting the vselect for the v4i
|
|
|
|
+; condition operand and widening the resulting vselect for the v4f32 result.
|
|
|
|
+; PR18036
|
|
|
|
+
|
|
|
|
+; CHECK-LABEL: vselect
|
|
|
|
+define <4 x float> @vselect(<4 x float>*%p, <4 x i32> %q) {
|
|
|
|
+entry:
|
|
|
|
+ %a1 = icmp eq <4 x i32> %q, zeroinitializer
|
|
|
|
+ %a14 = select <4 x i1> %a1, <4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+0> , <4 x float> zeroinitializer
|
|
|
|
+ ret <4 x float> %a14
|
|
|
|
+}
|
|
|
|
Index: lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
|
|
|
|
===================================================================
|
|
|
|
--- lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
|
|
|
|
+++ lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
|
|
|
|
@@ -2180,6 +2180,17 @@ SDValue DAGTypeLegalizer::WidenVecRes_SELECT(SDNod
|
|
|
|
if (getTypeAction(CondVT) == TargetLowering::TypeWidenVector)
|
|
|
|
Cond1 = GetWidenedVector(Cond1);
|
|
|
|
|
|
|
|
+ // If we have to split the condition there is no point in widening the
|
|
|
|
+ // select. This would result in an cycle of widening the select ->
|
|
|
|
+ // widening the condition operand -> splitting the condition operand ->
|
|
|
|
+ // splitting the select -> widening the select. Instead split this select
|
|
|
|
+ // further and widen the resulting type.
|
|
|
|
+ if (getTypeAction(CondVT) == TargetLowering::TypeSplitVector) {
|
|
|
|
+ SDValue SplitSelect = SplitVecOp_VSELECT(N, 0);
|
|
|
|
+ SDValue Res = ModifyToType(SplitSelect, WidenVT);
|
|
|
|
+ return Res;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
if (Cond1.getValueType() != CondWidenVT)
|
|
|
|
Cond1 = ModifyToType(Cond1, CondWidenVT);
|
|
|
|
}
|