Fix PR10475

- ISD::SHL/SRL/SRA must have either both scalar or both vector operands
  but TLI.getShiftAmountTy() so far only return scalar type. As a
  result, backend logic assuming that breaks.
- Rename the original TLI.getShiftAmountTy() to
  TLI.getScalarShiftAmountTy() and re-define TLI.getShiftAmountTy() to
  return target-specificed scalar type or the same vector type as the
  1st operand.
- Fix most TICG logic assuming TLI.getShiftAmountTy() a simple scalar
  type.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@176364 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Michael Liao 2013-03-01 18:40:30 +00:00
parent b8f307b2d6
commit a6b20ced76
14 changed files with 69 additions and 23 deletions

View File

@ -311,8 +311,10 @@ namespace ISD {
/// the shift amount can be any type, but care must be taken to ensure it is
/// large enough. TLI.getShiftAmountTy() is i8 on some targets, but before
/// legalization, types like i1024 can occur and i8 doesn't have enough bits
/// to represent the shift amount. By convention, DAGCombine and
/// SelectionDAGBuilder forces these shift amounts to i32 for simplicity.
/// to represent the shift amount.
/// When the 1st operand is a vector, the shift amount must be in the same
/// type. (TLI.getShiftAmountTy() will return the same type when the input
/// type is a vector.)
SHL, SRA, SRL, ROTL, ROTR,
/// Byte Swap and Counting operators.

View File

@ -145,7 +145,9 @@ public:
// the pointer type from the data layout.
// FIXME: The default needs to be removed once all the code is updated.
virtual MVT getPointerTy(uint32_t AS = 0) const { return PointerTy; }
virtual MVT getShiftAmountTy(EVT LHSTy) const;
virtual MVT getScalarShiftAmountTy(EVT LHSTy) const;
EVT getShiftAmountTy(EVT LHSTy) const;
/// isSelectExpensive - Return true if the select operation is expensive for
/// this target.

View File

@ -531,9 +531,10 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) {
}
SDValue DAGTypeLegalizer::PromoteIntRes_SHL(SDNode *N) {
return DAG.getNode(ISD::SHL, N->getDebugLoc(),
TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)),
GetPromotedInteger(N->getOperand(0)), N->getOperand(1));
SDValue Res = GetPromotedInteger(N->getOperand(0));
SDValue Amt = N->getOperand(1);
Amt = Amt.getValueType().isVector() ? ZExtPromotedInteger(Amt) : Amt;
return DAG.getNode(ISD::SHL, N->getDebugLoc(), Res.getValueType(), Res, Amt);
}
SDValue DAGTypeLegalizer::PromoteIntRes_SIGN_EXTEND_INREG(SDNode *N) {
@ -555,16 +556,17 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SimpleIntBinOp(SDNode *N) {
SDValue DAGTypeLegalizer::PromoteIntRes_SRA(SDNode *N) {
// The input value must be properly sign extended.
SDValue Res = SExtPromotedInteger(N->getOperand(0));
return DAG.getNode(ISD::SRA, N->getDebugLoc(),
Res.getValueType(), Res, N->getOperand(1));
SDValue Amt = N->getOperand(1);
Amt = Amt.getValueType().isVector() ? ZExtPromotedInteger(Amt) : Amt;
return DAG.getNode(ISD::SRA, N->getDebugLoc(), Res.getValueType(), Res, Amt);
}
SDValue DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) {
// The input value must be properly zero extended.
EVT VT = N->getValueType(0);
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
SDValue Res = ZExtPromotedInteger(N->getOperand(0));
return DAG.getNode(ISD::SRL, N->getDebugLoc(), NVT, Res, N->getOperand(1));
SDValue Amt = N->getOperand(1);
Amt = Amt.getValueType().isVector() ? ZExtPromotedInteger(Amt) : Amt;
return DAG.getNode(ISD::SRL, N->getDebugLoc(), Res.getValueType(), Res, Amt);
}
SDValue DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) {
@ -2101,8 +2103,9 @@ void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N,
// have an illegal type. Fix that first by casting the operand, otherwise
// the new SHL_PARTS operation would need further legalization.
SDValue ShiftOp = N->getOperand(1);
MVT ShiftTy = TLI.getShiftAmountTy(VT);
assert(ShiftTy.getSizeInBits() >= Log2_32_Ceil(VT.getSizeInBits()) &&
EVT ShiftTy = TLI.getShiftAmountTy(VT);
assert(ShiftTy.getScalarType().getSizeInBits() >=
Log2_32_Ceil(VT.getScalarType().getSizeInBits()) &&
"ShiftAmountTy is too small to cover the range of this type!");
if (ShiftOp.getValueType() != ShiftTy)
ShiftOp = DAG.getZExtOrTrunc(ShiftOp, dl, ShiftTy);

View File

@ -1518,7 +1518,7 @@ SDValue SelectionDAG::getMDNode(const MDNode *MD) {
/// the target's desired shift amount type.
SDValue SelectionDAG::getShiftAmountOperand(EVT LHSTy, SDValue Op) {
EVT OpTy = Op.getValueType();
MVT ShTy = TLI.getShiftAmountTy(LHSTy);
EVT ShTy = TLI.getShiftAmountTy(LHSTy);
if (OpTy == ShTy || OpTy.isVector()) return Op;
ISD::NodeType Opcode = OpTy.bitsGT(ShTy) ? ISD::TRUNCATE : ISD::ZERO_EXTEND;
@ -2912,6 +2912,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, EVT VT, SDValue N1,
"Shift operators return type must be the same as their first arg");
assert(VT.isInteger() && N2.getValueType().isInteger() &&
"Shifts only work on integers");
assert((!VT.isVector() || VT == N2.getValueType()) &&
"Vector shift amounts must be in the same as their first arg");
// Verify that the shift amount VT is bit enough to hold valid shift
// amounts. This catches things like trying to shift an i1024 value by an
// i8, which is easy to fall into in generic code that uses

View File

@ -2661,7 +2661,7 @@ void SelectionDAGBuilder::visitShift(const User &I, unsigned Opcode) {
SDValue Op1 = getValue(I.getOperand(0));
SDValue Op2 = getValue(I.getOperand(1));
MVT ShiftTy = TLI.getShiftAmountTy(Op2.getValueType());
EVT ShiftTy = TLI.getShiftAmountTy(Op2.getValueType());
// Coerce the shift amount to the right type if we can.
if (!I.getType()->isVectorTy() && Op2.getValueType() != ShiftTy) {

View File

@ -744,10 +744,17 @@ TargetLoweringBase::~TargetLoweringBase() {
delete &TLOF;
}
MVT TargetLoweringBase::getShiftAmountTy(EVT LHSTy) const {
MVT TargetLoweringBase::getScalarShiftAmountTy(EVT LHSTy) const {
return MVT::getIntegerVT(8*TD->getPointerSize(0));
}
EVT TargetLoweringBase::getShiftAmountTy(EVT LHSTy) const {
assert(LHSTy.isInteger() && "Shift amount is not an integer type!");
if (LHSTy.isVector())
return LHSTy;
return getScalarShiftAmountTy(LHSTy);
}
/// canOpTrap - Returns true if the operation can trap for the value type.
/// VT must be a legal type.
bool TargetLoweringBase::canOpTrap(unsigned Op, EVT VT) const {

View File

@ -73,7 +73,7 @@ namespace llvm {
public:
explicit MSP430TargetLowering(MSP430TargetMachine &TM);
virtual MVT getShiftAmountTy(EVT LHSTy) const { return MVT::i8; }
virtual MVT getScalarShiftAmountTy(EVT LHSTy) const { return MVT::i8; }
/// LowerOperation - Provide custom lowering hooks for some operations.
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;

View File

@ -151,7 +151,7 @@ namespace llvm {
public:
explicit MipsTargetLowering(MipsTargetMachine &TM);
virtual MVT getShiftAmountTy(EVT LHSTy) const { return MVT::i32; }
virtual MVT getScalarShiftAmountTy(EVT LHSTy) const { return MVT::i32; }
virtual bool allowsUnalignedMemoryAccesses (EVT VT, bool *Fast) const;

View File

@ -136,7 +136,7 @@ public:
NVPTXTargetMachine *nvTM;
// PTX always uses 32-bit shift amounts
virtual MVT getShiftAmountTy(EVT LHSTy) const {
virtual MVT getScalarShiftAmountTy(EVT LHSTy) const {
return MVT::i32;
}

View File

@ -329,7 +329,7 @@ namespace llvm {
/// DAG node.
virtual const char *getTargetNodeName(unsigned Opcode) const;
virtual MVT getShiftAmountTy(EVT LHSTy) const { return MVT::i32; }
virtual MVT getScalarShiftAmountTy(EVT LHSTy) const { return MVT::i32; }
/// getSetCCResultType - Return the ISD::SETCC ValueType
virtual EVT getSetCCResultType(EVT VT) const;

View File

@ -4956,7 +4956,7 @@ static SDValue getVShift(bool isLeft, EVT VT, SDValue SrcOp,
return DAG.getNode(ISD::BITCAST, dl, VT,
DAG.getNode(Opc, dl, ShVT, SrcOp,
DAG.getConstant(NumBits,
TLI.getShiftAmountTy(SrcOp.getValueType()))));
TLI.getScalarShiftAmountTy(SrcOp.getValueType()))));
}
SDValue

View File

@ -471,7 +471,7 @@ namespace llvm {
virtual unsigned getJumpTableEncoding() const;
virtual MVT getShiftAmountTy(EVT LHSTy) const { return MVT::i8; }
virtual MVT getScalarShiftAmountTy(EVT LHSTy) const { return MVT::i8; }
virtual const MCExpr *
LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI,

View File

@ -84,7 +84,7 @@ namespace llvm {
explicit XCoreTargetLowering(XCoreTargetMachine &TM);
virtual unsigned getJumpTableEncoding() const;
virtual MVT getShiftAmountTy(EVT LHSTy) const { return MVT::i32; }
virtual MVT getScalarShiftAmountTy(EVT LHSTy) const { return MVT::i32; }
/// LowerOperation - Provide custom lowering hooks for some operations.
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;

View File

@ -0,0 +1,30 @@
; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=corei7-avx
; No check in a crash test
define void @autogen_262380_1000() {
BB:
br label %CF79
CF79: ; preds = %CF79, %BB
br i1 undef, label %CF79, label %CF84.critedge.critedge
CF84.critedge.critedge: ; preds = %CF79
%L35 = load <8 x i32>* undef
br label %CF85
CF85: ; preds = %CF85, %CF84.critedge.critedge
br i1 undef, label %CF85, label %CF86
CF86: ; preds = %CF86, %CF85
%B61 = sub <8 x i32> %L35, zeroinitializer
%S64 = icmp ne <8 x i32> %B61, zeroinitializer
%E73 = extractelement <8 x i1> %S64, i32 6
br i1 %E73, label %CF86, label %CF87
CF87: ; preds = %CF87, %CF86
br i1 undef, label %CF87, label %CF88
CF88: ; preds = %CF87
ret void
}