Add vector shifts to the IR, patch by Eli Friedman.

CodeGen & Clang work coming next.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54161 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nate Begeman 2008-07-29 15:49:41 +00:00
parent 75cf9cc527
commit 5bc1ea0736
11 changed files with 361 additions and 319 deletions

View File

@ -2458,9 +2458,8 @@ the left a specified number of bits.</p>
<h5>Arguments:</h5>
<p>Both arguments to the '<tt>shl</tt>' instruction must be the same <a
href="#t_integer">integer</a> type. '<tt>var2</tt>' is treated as an
unsigned value. This instruction does not support
<a href="#t_vector">vector</a> operands.</p>
href="#t_integer">integer</a> or <a href="#t_vector">vector</a> of integer
type. '<tt>var2</tt>' is treated as an unsigned value.</p>
<h5>Semantics:</h5>
@ -2489,9 +2488,8 @@ operand shifted to the right a specified number of bits with zero fill.</p>
<h5>Arguments:</h5>
<p>Both arguments to the '<tt>lshr</tt>' instruction must be the same
<a href="#t_integer">integer</a> type. '<tt>var2</tt>' is treated as an
unsigned value. This instruction does not support
<a href="#t_vector">vector</a> operands.</p>
<a href="#t_integer">integer</a> or <a href="#t_vector">vector</a> of integer
type. '<tt>var2</tt>' is treated as an unsigned value.</p>
<h5>Semantics:</h5>
@ -2525,9 +2523,8 @@ operand shifted to the right a specified number of bits with sign extension.</p>
<h5>Arguments:</h5>
<p>Both arguments to the '<tt>ashr</tt>' instruction must be the same
<a href="#t_integer">integer</a> type. '<tt>var2</tt>' is treated as an
unsigned value. This instruction does not support
<a href="#t_vector">vector</a> operands.</p>
<a href="#t_integer">integer</a> or <a href="#t_vector">vector</a> of integer
type. '<tt>var2</tt>' is treated as an unsigned value.</p>
<h5>Semantics:</h5>
<p>This instruction always performs an arithmetic shift right operation,

File diff suppressed because it is too large Load Diff

View File

@ -354,7 +354,7 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
#line 967 "/Users/gohman/LLVM/llvm/lib/AsmParser/llvmAsmParser.y"
#line 967 "/llvm/lib/AsmParser/llvmAsmParser.y"
{
llvm::Module *ModuleVal;
llvm::Function *FunctionVal;

View File

@ -1945,7 +1945,7 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
if ($3->getType() != $5->getType())
GEN_ERROR("Logical operator types must match");
if (!$3->getType()->isInteger()) {
if (Instruction::isShift($1) || !isa<VectorType>($3->getType()) ||
if (!isa<VectorType>($3->getType()) ||
!cast<VectorType>($3->getType())->getElementType()->isInteger())
GEN_ERROR("Logical operator requires integral operands");
}
@ -3013,7 +3013,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
if (!(*$2)->isInteger()) {
if (Instruction::isShift($1) || !isa<VectorType>($2->get()) ||
if (!isa<VectorType>($2->get()) ||
!cast<VectorType>($2->get())->getElementType()->isInteger())
GEN_ERROR("Logical operator requires integral operands");
}

View File

@ -1945,7 +1945,7 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
if ($3->getType() != $5->getType())
GEN_ERROR("Logical operator types must match");
if (!$3->getType()->isInteger()) {
if (Instruction::isShift($1) || !isa<VectorType>($3->getType()) ||
if (!isa<VectorType>($3->getType()) ||
!cast<VectorType>($3->getType())->getElementType()->isInteger())
GEN_ERROR("Logical operator requires integral operands");
}
@ -3013,7 +3013,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
if (!(*$2)->isInteger()) {
if (Instruction::isShift($1) || !isa<VectorType>($2->get()) ||
if (!isa<VectorType>($2->get()) ||
!cast<VectorType>($2->get())->getElementType()->isInteger())
GEN_ERROR("Logical operator requires integral operands");
}

View File

@ -2958,7 +2958,17 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Tmp2 = PromoteOp(Node->getOperand(1)); // Promote the RHS.
break;
}
if ((Node->getOpcode() == ISD::SHL ||
Node->getOpcode() == ISD::SRL ||
Node->getOpcode() == ISD::SRA) &&
!Node->getValueType(0).isVector()) {
if (TLI.getShiftAmountTy().bitsLT(Tmp2.getValueType()))
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);
switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
@ -2966,8 +2976,11 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
case TargetLowering::Legal: break;
case TargetLowering::Custom:
Tmp1 = TLI.LowerOperation(Result, DAG);
if (Tmp1.Val) Result = Tmp1;
break;
if (Tmp1.Val) {
Result = Tmp1;
break;
}
// Fall through if the custom lower can't deal with the operation
case TargetLowering::Expand: {
MVT VT = Op.getValueType();

View File

@ -2407,11 +2407,12 @@ void SelectionDAGLowering::visitBinary(User &I, unsigned OpCode) {
void SelectionDAGLowering::visitShift(User &I, unsigned Opcode) {
SDValue Op1 = getValue(I.getOperand(0));
SDValue Op2 = getValue(I.getOperand(1));
if (TLI.getShiftAmountTy().bitsLT(Op2.getValueType()))
Op2 = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), Op2);
else if (TLI.getShiftAmountTy().bitsGT(Op2.getValueType()))
Op2 = DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), Op2);
if (!isa<VectorType>(I.getType())) {
if (TLI.getShiftAmountTy().bitsLT(Op2.getValueType()))
Op2 = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), Op2);
else if (TLI.getShiftAmountTy().bitsGT(Op2.getValueType()))
Op2 = DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), Op2);
}
setValue(&I, DAG.getNode(Opcode, Op1.getValueType(), Op1, Op2));
}

View File

@ -6368,7 +6368,8 @@ Instruction *InstCombiner::visitAShr(BinaryOperator &I) {
return ReplaceInstUsesWith(I, CSI);
// See if we can turn a signed shr into an unsigned shr.
if (MaskedValueIsZero(Op0,
if (!isa<VectorType>(I.getType()) &&
MaskedValueIsZero(Op0,
APInt::getSignBit(I.getType()->getPrimitiveSizeInBits())))
return BinaryOperator::CreateLShr(Op0, I.getOperand(1));

View File

@ -874,6 +874,7 @@ void LoadInst::setAlignment(unsigned Align) {
//===----------------------------------------------------------------------===//
void StoreInst::AssertOK() {
assert(getOperand(0) && getOperand(1) && "Both operands must be non-null!");
assert(isa<PointerType>(getOperand(1)->getType()) &&
"Ptr must have pointer type!");
assert(getOperand(0)->getType() ==
@ -1535,8 +1536,10 @@ void BinaryOperator::init(BinaryOps iType) {
case AShr:
assert(getType() == LHS->getType() &&
"Shift operation should return same type as operands!");
assert(getType()->isInteger() &&
"Shift operation requires integer operands");
assert((getType()->isInteger() ||
(isa<VectorType>(getType()) &&
cast<VectorType>(getType())->getElementType()->isInteger())) &&
"Tried to create a shift operation on a non-integral type!");
break;
case And: case Or:
case Xor:

View File

@ -973,8 +973,10 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) {
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
Assert1(B.getType()->isInteger(),
"Shift must return an integer result!", &B);
Assert1(B.getType()->isInteger() ||
(isa<VectorType>(B.getType()) &&
cast<VectorType>(B.getType())->getElementType()->isInteger()),
"Shifts only work with integral types!", &B);
Assert1(B.getType() == B.getOperand(0)->getType(),
"Shift return type must be same as operands!", &B);
/* FALL THROUGH */
@ -1041,9 +1043,13 @@ void Verifier::visitShuffleVectorInst(ShuffleVectorInst &SV) {
// Check to see if Mask is valid.
if (const ConstantVector *MV = dyn_cast<ConstantVector>(SV.getOperand(2))) {
for (unsigned i = 0, e = MV->getNumOperands(); i != e; ++i) {
Assert1(isa<ConstantInt>(MV->getOperand(i)) ||
isa<UndefValue>(MV->getOperand(i)),
"Invalid shufflevector shuffle mask!", &SV);
if (ConstantInt* CI = dyn_cast<ConstantInt>(MV->getOperand(i))) {
Assert1(!CI->uge(MV->getNumOperands()*2),
"Invalid shufflevector shuffle mask!", &SV);
} else {
Assert1(isa<UndefValue>(MV->getOperand(i)),
"Invalid shufflevector shuffle mask!", &SV);
}
}
} else {
Assert1(isa<UndefValue>(SV.getOperand(2)) ||

View File

@ -0,0 +1,21 @@
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | grep shl
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | grep ashr
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | grep lshr
define <4 x i32> @foo(<4 x i32> %a, <4 x i32> %b) nounwind {
entry:
%cmp = shl <4 x i32> %a, %b ; <4 x i32> [#uses=1]
ret <4 x i32> %cmp
}
define <4 x i32> @bar(<4 x i32> %a, <4 x i32> %b) nounwind {
entry:
%cmp = lshr <4 x i32> %a, %b ; <4 x i32> [#uses=1]
ret <4 x i32> %cmp
}
define <4 x i32> @baz(<4 x i32> %a, <4 x i32> %b) nounwind {
entry:
%cmp = ashr <4 x i32> %a, %b ; <4 x i32> [#uses=1]
ret <4 x i32> %cmp
}