mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-27 02:31:09 +00:00
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:
parent
75cf9cc527
commit
5bc1ea0736
@ -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
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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)) ||
|
||||
|
21
test/Assembler/vector-shift.ll
Normal file
21
test/Assembler/vector-shift.ll
Normal 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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user