1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

Fix getNode to allow a vector for the shift amount for shifts of vectors.

Fix the shift amount when unrolling a vector shift into scalar shifts.
Fix problem in getShuffleScalarElt where it assumes that the input of
a bit convert must be a vector.

llvm-svn: 60740
This commit is contained in:
Mon P Wang 2008-12-09 05:46:39 +00:00
parent e32dbaddd2
commit 0c011f8ba9
4 changed files with 44 additions and 9 deletions

View File

@ -2591,6 +2591,7 @@ equal to or larger than the number of bits in <tt>op1</tt>, the result is undefi
&lt;result&gt; = shl i32 4, 2 <i>; yields {i32}: 16</i> &lt;result&gt; = shl i32 4, 2 <i>; yields {i32}: 16</i>
&lt;result&gt; = shl i32 1, 10 <i>; yields {i32}: 1024</i> &lt;result&gt; = shl i32 1, 10 <i>; yields {i32}: 1024</i>
&lt;result&gt; = shl i32 1, 32 <i>; undefined</i> &lt;result&gt; = shl i32 1, 32 <i>; undefined</i>
&lt;result&gt; = shl &lt;2 x i32&gt; &lt; i32 1, i32 1&gt;, &lt; i32 1, i32 2&gt; <i>; yields: result=&lt;2 x i32&gt; &lt; i32 2, i32 4&gt;</i>
</pre> </pre>
</div> </div>
<!-- _______________________________________________________________________ --> <!-- _______________________________________________________________________ -->
@ -2624,6 +2625,7 @@ the number of bits in <tt>op1</tt>, the result is undefined.</p>
&lt;result&gt; = lshr i8 4, 3 <i>; yields {i8}:result = 0</i> &lt;result&gt; = lshr i8 4, 3 <i>; yields {i8}:result = 0</i>
&lt;result&gt; = lshr i8 -2, 1 <i>; yields {i8}:result = 0x7FFFFFFF </i> &lt;result&gt; = lshr i8 -2, 1 <i>; yields {i8}:result = 0x7FFFFFFF </i>
&lt;result&gt; = lshr i32 1, 32 <i>; undefined</i> &lt;result&gt; = lshr i32 1, 32 <i>; undefined</i>
&lt;result&gt; = lshr &lt;2 x i32&gt; &lt; i32 -2, i32 4&gt;, &lt; i32 1, i32 2&gt; <i>; yields: result=&lt;2 x i32&gt; &lt; i32 0x7FFFFFFF, i32 1&gt;</i>
</pre> </pre>
</div> </div>
@ -2659,6 +2661,7 @@ larger than the number of bits in <tt>op1</tt>, the result is undefined.
&lt;result&gt; = ashr i8 4, 3 <i>; yields {i8}:result = 0</i> &lt;result&gt; = ashr i8 4, 3 <i>; yields {i8}:result = 0</i>
&lt;result&gt; = ashr i8 -2, 1 <i>; yields {i8}:result = -1</i> &lt;result&gt; = ashr i8 -2, 1 <i>; yields {i8}:result = -1</i>
&lt;result&gt; = ashr i32 1, 32 <i>; undefined</i> &lt;result&gt; = ashr i32 1, 32 <i>; undefined</i>
&lt;result&gt; = ashr &lt;2 x i32&gt; &lt; i32 -2, i32 4&gt;, &lt; i32 1, i32 3&gt; <i>; yields: result=&lt;2 x i32&gt; &lt; i32 -1, i32 0&gt;</i>
</pre> </pre>
</div> </div>

View File

@ -297,6 +297,9 @@ private:
SDValue ExpandEXTRACT_SUBVECTOR(SDValue Op); SDValue ExpandEXTRACT_SUBVECTOR(SDValue Op);
SDValue ExpandEXTRACT_VECTOR_ELT(SDValue Op); SDValue ExpandEXTRACT_VECTOR_ELT(SDValue Op);
// Returns the legalized (truncated or extended) shift amount.
SDValue LegalizeShiftAmount(SDValue ShiftAmt);
}; };
} }
@ -786,8 +789,19 @@ SDValue SelectionDAGLegalize::UnrollVectorOp(SDValue Op) {
Operands[j] = Operand; Operands[j] = Operand;
} }
} }
switch (Op.getOpcode()) {
default:
Scalars.push_back(DAG.getNode(Op.getOpcode(), EltVT, Scalars.push_back(DAG.getNode(Op.getOpcode(), EltVT,
&Operands[0], Operands.size())); &Operands[0], Operands.size()));
break;
case ISD::SHL:
case ISD::SRA:
case ISD::SRL:
Scalars.push_back(DAG.getNode(Op.getOpcode(), EltVT, Operands[0],
LegalizeShiftAmount(Operands[1])));
break;
}
} }
return DAG.getNode(ISD::BUILD_VECTOR, VT, &Scalars[0], Scalars.size()); return DAG.getNode(ISD::BUILD_VECTOR, VT, &Scalars[0], Scalars.size());
@ -850,6 +864,17 @@ PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx) {
PseudoSourceValue::getFixedStack(SPFI), 0); PseudoSourceValue::getFixedStack(SPFI), 0);
} }
SDValue SelectionDAGLegalize::LegalizeShiftAmount(SDValue ShiftAmt) {
if (TLI.getShiftAmountTy().bitsLT(ShiftAmt.getValueType()))
return DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), ShiftAmt);
if (TLI.getShiftAmountTy().bitsGT(ShiftAmt.getValueType()))
return DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), ShiftAmt);
return ShiftAmt;
}
/// LegalizeOp - We know that the specified value has a legal type, and /// LegalizeOp - We know that the specified value has a legal type, and
/// that its operands are legal. Now ensure that the operation itself /// that its operands are legal. Now ensure that the operation itself
/// is legal, recursively ensuring that the operands' operations remain /// is legal, recursively ensuring that the operands' operations remain
@ -3094,10 +3119,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Node->getOpcode() == ISD::SRL || Node->getOpcode() == ISD::SRL ||
Node->getOpcode() == ISD::SRA) && Node->getOpcode() == ISD::SRA) &&
!Node->getValueType(0).isVector()) { !Node->getValueType(0).isVector()) {
if (TLI.getShiftAmountTy().bitsLT(Tmp2.getValueType())) Tmp2 = LegalizeShiftAmount(Tmp2);
Tmp2 = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), Tmp2);
else if (TLI.getShiftAmountTy().bitsGT(Tmp2.getValueType()))
Tmp2 = DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), Tmp2);
} }
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);

View File

@ -2066,7 +2066,8 @@ SDValue SelectionDAG::getShuffleScalarElt(const SDNode *N, unsigned i) {
if (V.getOpcode() == ISD::BIT_CONVERT) { if (V.getOpcode() == ISD::BIT_CONVERT) {
V = V.getOperand(0); V = V.getOperand(0);
if (V.getValueType().getVectorNumElements() != NumElems) MVT VVT = V.getValueType();
if (!VVT.isVector() || VVT.getVectorNumElements() != NumElems)
return SDValue(); return SDValue();
} }
if (V.getOpcode() == ISD::SCALAR_TO_VECTOR) if (V.getOpcode() == ISD::SCALAR_TO_VECTOR)
@ -2418,7 +2419,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
"Shift operators return type must be the same as their first arg"); "Shift operators return type must be the same as their first arg");
assert(VT.isInteger() && N2.getValueType().isInteger() && assert(VT.isInteger() && N2.getValueType().isInteger() &&
"Shifts only work on integers"); "Shifts only work on integers");
assert(N2.getValueType() == TLI.getShiftAmountTy() && assert((N2.getValueType() == TLI.getShiftAmountTy() ||
(N2.getValueType().isVector() && N2.getValueType().isInteger())) &&
"Wrong type for shift amount"); "Wrong type for shift amount");
// Always fold shifts of i1 values so the code generator doesn't need to // Always fold shifts of i1 values so the code generator doesn't need to

View File

@ -0,0 +1,8 @@
; RUN: llvm-as < %s | llc
; Example that requires splitting and expanding a vector shift.
define <2 x i64> @update(<2 x i64> %val) nounwind readnone {
entry:
%shr = lshr <2 x i64> %val, < i64 2, i64 2 > ; <<2 x i64>> [#uses=1]
ret <2 x i64> %shr
}