summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnold Schwaighofer <aschwaighofer@apple.com>2014-03-07 23:25:55 +0000
committerArnold Schwaighofer <aschwaighofer@apple.com>2014-03-07 23:25:55 +0000
commitaa5b17b359fca123952666cd3cbff2c228042114 (patch)
treee0a959db7c2dce6148deb5b5e45de7322473fcdb
parentbd86fbe0d721aaa949d9a7be25fa7ae4d89972b7 (diff)
downloadllvm-aa5b17b359fca123952666cd3cbff2c228042114.tar.gz
llvm-aa5b17b359fca123952666cd3cbff2c228042114.tar.bz2
llvm-aa5b17b359fca123952666cd3cbff2c228042114.tar.xz
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203311 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp11
-rw-r--r--test/CodeGen/X86/sse1.ll14
2 files changed, 25 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 2db913d4f1..4f57bc3201 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -2192,6 +2192,17 @@ SDValue DAGTypeLegalizer::WidenVecRes_SELECT(SDNode *N) {
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);
}
diff --git a/test/CodeGen/X86/sse1.ll b/test/CodeGen/X86/sse1.ll
index 47c6429b18..183297e4c3 100644
--- a/test/CodeGen/X86/sse1.ll
+++ b/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
+}