OSDN Git Service

When the legalizer is splitting vector shifts, the result may not have the right...
authorBenjamin Kramer <benny.kra@googlemail.com>
Sun, 27 Jan 2013 11:19:11 +0000 (11:19 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Sun, 27 Jan 2013 11:19:11 +0000 (11:19 +0000)
Fix that by adding a cast to the shift expander. This came up with vector shifts
on sse-less X86 CPUs.

   <2 x i64>       = shl <2 x i64> <2 x i64>
-> i64,i64         = shl i64 i64; shl i64 i64
-> i32,i32,i32,i32 = shl_parts i32 i32 i64; shl_parts i32 i32 i64

Now we cast the last two i64s to the right type. Fixes the crash in PR14668.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173615 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
test/CodeGen/X86/legalize-shift-64.ll

index 5da6d29..e08dd6d 100644 (file)
@@ -2095,9 +2095,16 @@ void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N,
     // Expand the subcomponents.
     SDValue LHSL, LHSH;
     GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
-
-    SDValue Ops[] = { LHSL, LHSH, N->getOperand(1) };
     EVT VT = LHSL.getValueType();
+
+    // If the shift amount operand is coming from a vector legalization it may
+    // not have the right return type.  Fix that first by casting the operand.
+    SDValue ShiftOp = N->getOperand(1);
+    MVT ShiftTy = TLI.getShiftAmountTy(VT);
+    if (ShiftOp.getValueType() != ShiftTy)
+      ShiftOp = DAG.getZExtOrTrunc(ShiftOp, dl, ShiftTy);
+
+    SDValue Ops[] = { LHSL, LHSH, ShiftOp };
     Lo = DAG.getNode(PartsOpc, dl, DAG.getVTList(VT, VT), Ops, 3);
     Hi = Lo.getValue(1);
     return;
index c9f2fc2..71ef2d3 100644 (file)
@@ -54,3 +54,14 @@ define i64 @test4(i64 %xx, i32 %test) nounwind {
 ; CHECK: orl   %esi, %eax
 ; CHECK: sarl  %cl, %edx
 }
+
+; PR14668
+define <2 x i64> @test5(<2 x i64> %A, <2 x i64> %B) {
+  %shl = shl <2 x i64> %A, %B
+  ret <2 x i64> %shl
+; CHECK: test5
+; CHECK: shl
+; CHECK: shldl
+; CHECK: shl
+; CHECK: shldl
+}