GlobalISel: Change representation of shuffle masks

Currently shufflemasks get emitted as any other constant, and you end
up with a bunch of virtual registers of G_CONSTANT with a
G_BUILD_VECTOR. The AArch64 selector then asserts on anything that
doesn't fit this pattern. This isn't an ideal representation, and
should avoid legalization and have fewer opportunities for a
representational error.

Rather than invent a new shuffle mask operand type, similar to what
ShuffleVectorSDNode does, just track the original IR Constant mask
operand. I don't completely like the idea of adding another link to
the IR, but MIR is already quite dependent on IR constants already,
and this will allow sharing the shuffle mask utility functions with
the IR.

llvm-svn: 368704
This commit is contained in:
Matt Arsenault 2019-08-13 15:34:38 +00:00
parent 8a033a9e3f
commit 5af9cf042f
25 changed files with 446 additions and 150 deletions

View File

@ -250,6 +250,11 @@ public:
return *this; return *this;
} }
const MachineInstrBuilder &addShuffleMask(const Constant *Val) const {
MI->addOperand(*MF, MachineOperand::CreateShuffleMask(Val));
return *this;
}
const MachineInstrBuilder &addSym(MCSymbol *Sym, const MachineInstrBuilder &addSym(MCSymbol *Sym,
unsigned char TargetFlags = 0) const { unsigned char TargetFlags = 0) const {
MI->addOperand(*MF, MachineOperand::CreateMCSymbol(Sym, TargetFlags)); MI->addOperand(*MF, MachineOperand::CreateMCSymbol(Sym, TargetFlags));

View File

@ -23,6 +23,7 @@
namespace llvm { namespace llvm {
class BlockAddress; class BlockAddress;
class Constant;
class ConstantFP; class ConstantFP;
class ConstantInt; class ConstantInt;
class GlobalValue; class GlobalValue;
@ -68,7 +69,8 @@ public:
MO_CFIIndex, ///< MCCFIInstruction index. MO_CFIIndex, ///< MCCFIInstruction index.
MO_IntrinsicID, ///< Intrinsic ID for ISel MO_IntrinsicID, ///< Intrinsic ID for ISel
MO_Predicate, ///< Generic predicate for ISel MO_Predicate, ///< Generic predicate for ISel
MO_Last = MO_Predicate, MO_ShuffleMask, ///< Other IR Constant for ISel (shuffle masks)
MO_Last = MO_ShuffleMask
}; };
private: private:
@ -172,6 +174,7 @@ private:
unsigned CFIIndex; // For MO_CFI. unsigned CFIIndex; // For MO_CFI.
Intrinsic::ID IntrinsicID; // For MO_IntrinsicID. Intrinsic::ID IntrinsicID; // For MO_IntrinsicID.
unsigned Pred; // For MO_Predicate unsigned Pred; // For MO_Predicate
const Constant *ShuffleMask; // For MO_ShuffleMask
struct { // For MO_Register. struct { // For MO_Register.
// Register number is in SmallContents.RegNo. // Register number is in SmallContents.RegNo.
@ -341,6 +344,7 @@ public:
bool isCFIIndex() const { return OpKind == MO_CFIIndex; } bool isCFIIndex() const { return OpKind == MO_CFIIndex; }
bool isIntrinsicID() const { return OpKind == MO_IntrinsicID; } bool isIntrinsicID() const { return OpKind == MO_IntrinsicID; }
bool isPredicate() const { return OpKind == MO_Predicate; } bool isPredicate() const { return OpKind == MO_Predicate; }
bool isShuffleMask() const { return OpKind == MO_ShuffleMask; }
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Accessors for Register Operands // Accessors for Register Operands
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
@ -579,6 +583,11 @@ public:
return Contents.Pred; return Contents.Pred;
} }
const Constant *getShuffleMask() const {
assert(isShuffleMask() && "Wrong MachineOperand accessor");
return Contents.ShuffleMask;
}
/// Return the offset from the symbol in this operand. This always returns 0 /// Return the offset from the symbol in this operand. This always returns 0
/// for ExternalSymbol operands. /// for ExternalSymbol operands.
int64_t getOffset() const { int64_t getOffset() const {
@ -902,6 +911,12 @@ public:
return Op; return Op;
} }
static MachineOperand CreateShuffleMask(const Constant *C) {
MachineOperand Op(MachineOperand::MO_ShuffleMask);
Op.Contents.ShuffleMask = C;
return Op;
}
friend class MachineInstr; friend class MachineInstr;
friend class MachineRegisterInfo; friend class MachineRegisterInfo;

View File

@ -967,9 +967,12 @@ def G_EXTRACT_VECTOR_ELT : GenericInstruction {
} }
// Generic shufflevector. // Generic shufflevector.
//
// The mask operand should be an IR Constant which exactly matches the
// corresponding mask for the IR shufflevector instruction.
def G_SHUFFLE_VECTOR: GenericInstruction { def G_SHUFFLE_VECTOR: GenericInstruction {
let OutOperandList = (outs type0:$dst); let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$v1, type1:$v2, type2:$mask); let InOperandList = (ins type1:$v1, type1:$v2, unknown:$mask);
let hasSideEffects = 0; let hasSideEffects = 0;
} }

View File

@ -1902,7 +1902,7 @@ bool IRTranslator::translateShuffleVector(const User &U,
.addDef(getOrCreateVReg(U)) .addDef(getOrCreateVReg(U))
.addUse(getOrCreateVReg(*U.getOperand(0))) .addUse(getOrCreateVReg(*U.getOperand(0)))
.addUse(getOrCreateVReg(*U.getOperand(1))) .addUse(getOrCreateVReg(*U.getOperand(1)))
.addUse(getOrCreateVReg(*U.getOperand(2))); .addShuffleMask(cast<Constant>(U.getOperand(2)));
return true; return true;
} }

View File

@ -249,6 +249,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
.Case("successors", MIToken::kw_successors) .Case("successors", MIToken::kw_successors)
.Case("floatpred", MIToken::kw_floatpred) .Case("floatpred", MIToken::kw_floatpred)
.Case("intpred", MIToken::kw_intpred) .Case("intpred", MIToken::kw_intpred)
.Case("shufflemask", MIToken::kw_shufflemask)
.Case("pre-instr-symbol", MIToken::kw_pre_instr_symbol) .Case("pre-instr-symbol", MIToken::kw_pre_instr_symbol)
.Case("post-instr-symbol", MIToken::kw_post_instr_symbol) .Case("post-instr-symbol", MIToken::kw_post_instr_symbol)
.Case("unknown-size", MIToken::kw_unknown_size) .Case("unknown-size", MIToken::kw_unknown_size)

View File

@ -117,6 +117,7 @@ struct MIToken {
kw_successors, kw_successors,
kw_floatpred, kw_floatpred,
kw_intpred, kw_intpred,
kw_shufflemask,
kw_pre_instr_symbol, kw_pre_instr_symbol,
kw_post_instr_symbol, kw_post_instr_symbol,
kw_unknown_size, kw_unknown_size,
@ -146,6 +147,7 @@ struct MIToken {
IntegerLiteral, IntegerLiteral,
FloatingPointLiteral, FloatingPointLiteral,
HexLiteral, HexLiteral,
VectorLiteral,
VirtualRegister, VirtualRegister,
ConstantPoolItem, ConstantPoolItem,
JumpTableIndex, JumpTableIndex,

View File

@ -451,6 +451,7 @@ public:
bool parseBlockAddressOperand(MachineOperand &Dest); bool parseBlockAddressOperand(MachineOperand &Dest);
bool parseIntrinsicOperand(MachineOperand &Dest); bool parseIntrinsicOperand(MachineOperand &Dest);
bool parsePredicateOperand(MachineOperand &Dest); bool parsePredicateOperand(MachineOperand &Dest);
bool parseShuffleMaskOperand(MachineOperand &Dest);
bool parseTargetIndexOperand(MachineOperand &Dest); bool parseTargetIndexOperand(MachineOperand &Dest);
bool parseCustomRegisterMaskOperand(MachineOperand &Dest); bool parseCustomRegisterMaskOperand(MachineOperand &Dest);
bool parseLiveoutRegisterMaskOperand(MachineOperand &Dest); bool parseLiveoutRegisterMaskOperand(MachineOperand &Dest);
@ -2285,6 +2286,49 @@ bool MIParser::parsePredicateOperand(MachineOperand &Dest) {
return false; return false;
} }
bool MIParser::parseShuffleMaskOperand(MachineOperand &Dest) {
assert(Token.is(MIToken::kw_shufflemask));
lex();
if (expectAndConsume(MIToken::lparen))
return error("expected syntax shufflemask(<integer or undef>, ...)");
SmallVector<Constant *, 32> ShufMask;
LLVMContext &Ctx = MF.getFunction().getContext();
Type *I32Ty = Type::getInt32Ty(Ctx);
bool AllZero = true;
bool AllUndef = true;
do {
if (Token.is(MIToken::kw_undef)) {
ShufMask.push_back(UndefValue::get(I32Ty));
AllZero = false;
} else if (Token.is(MIToken::IntegerLiteral)) {
AllUndef = false;
const APSInt &Int = Token.integerValue();
if (!Int.isNullValue())
AllZero = false;
ShufMask.push_back(ConstantInt::get(I32Ty, Int.getExtValue()));
} else
return error("expected integer constant");
lex();
} while (consumeIfPresent(MIToken::comma));
if (expectAndConsume(MIToken::rparen))
return error("shufflemask should be terminated by ')'.");
if (AllZero || AllUndef) {
VectorType *VT = VectorType::get(I32Ty, ShufMask.size());
Constant *C = AllZero ? Constant::getNullValue(VT) : UndefValue::get(VT);
Dest = MachineOperand::CreateShuffleMask(C);
} else
Dest = MachineOperand::CreateShuffleMask(ConstantVector::get(ShufMask));
return false;
}
bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) { bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) {
assert(Token.is(MIToken::kw_target_index)); assert(Token.is(MIToken::kw_target_index));
lex(); lex();
@ -2432,6 +2476,8 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest,
case MIToken::kw_floatpred: case MIToken::kw_floatpred:
case MIToken::kw_intpred: case MIToken::kw_intpred:
return parsePredicateOperand(Dest); return parsePredicateOperand(Dest);
case MIToken::kw_shufflemask:
return parseShuffleMaskOperand(Dest);
case MIToken::Error: case MIToken::Error:
return true; return true;
case MIToken::Identifier: case MIToken::Identifier:

View File

@ -842,7 +842,8 @@ void MIPrinter::print(const MachineInstr &MI, unsigned OpIdx,
case MachineOperand::MO_CFIIndex: case MachineOperand::MO_CFIIndex:
case MachineOperand::MO_IntrinsicID: case MachineOperand::MO_IntrinsicID:
case MachineOperand::MO_Predicate: case MachineOperand::MO_Predicate:
case MachineOperand::MO_BlockAddress: { case MachineOperand::MO_BlockAddress:
case MachineOperand::MO_ShuffleMask: {
unsigned TiedOperandIdx = 0; unsigned TiedOperandIdx = 0;
if (ShouldPrintRegisterTies && Op.isReg() && Op.isTied() && !Op.isDef()) if (ShouldPrintRegisterTies && Op.isReg() && Op.isTied() && !Op.isDef())
TiedOperandIdx = Op.getParent()->findTiedOperandIdx(OpIdx); TiedOperandIdx = Op.getParent()->findTiedOperandIdx(OpIdx);

View File

@ -333,6 +333,8 @@ bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {
return getIntrinsicID() == Other.getIntrinsicID(); return getIntrinsicID() == Other.getIntrinsicID();
case MachineOperand::MO_Predicate: case MachineOperand::MO_Predicate:
return getPredicate() == Other.getPredicate(); return getPredicate() == Other.getPredicate();
case MachineOperand::MO_ShuffleMask:
return getShuffleMask() == Other.getShuffleMask();
} }
llvm_unreachable("Invalid machine operand type"); llvm_unreachable("Invalid machine operand type");
} }
@ -381,6 +383,8 @@ hash_code llvm::hash_value(const MachineOperand &MO) {
return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID()); return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID());
case MachineOperand::MO_Predicate: case MachineOperand::MO_Predicate:
return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate()); return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate());
case MachineOperand::MO_ShuffleMask:
return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getShuffleMask());
} }
llvm_unreachable("Invalid machine operand type"); llvm_unreachable("Invalid machine operand type");
} }
@ -936,6 +940,20 @@ void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
<< CmpInst::getPredicateName(Pred) << ')'; << CmpInst::getPredicateName(Pred) << ')';
break; break;
} }
case MachineOperand::MO_ShuffleMask:
OS << "shufflemask(";
const Constant* C = getShuffleMask();
const int NumElts = C->getType()->getVectorNumElements();
StringRef Separator;
for (int I = 0; I != NumElts; ++I) {
OS << Separator;
C->getAggregateElement(I)->printAsOperand(OS, false, MST);
Separator = ", ";
}
OS << ')';
break;
} }
} }

View File

@ -1387,6 +1387,22 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
report("G_SEXT_INREG size must be less than source bit width", MI); report("G_SEXT_INREG size must be less than source bit width", MI);
break; break;
} }
case TargetOpcode::G_SHUFFLE_VECTOR: {
const MachineOperand &MaskOp = MI->getOperand(3);
if (!MaskOp.isShuffleMask()) {
report("Incorrect mask operand type for G_SHUFFLE_VECTOR", MI);
break;
}
const Constant *Mask = MaskOp.getShuffleMask();
if (!Mask->getAggregateElement(0u)) {
report("Invalid shufflemask constant type", MI);
break;
}
// TODO: Verify element numbers consistent
break;
}
default: default:
break; break;
} }

View File

@ -115,8 +115,6 @@ private:
bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const; bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const; bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI) const;
void collectShuffleMaskIndices(MachineInstr &I, MachineRegisterInfo &MRI,
SmallVectorImpl<Optional<int>> &Idxs) const;
bool selectShuffleVector(MachineInstr &I, MachineRegisterInfo &MRI) const; bool selectShuffleVector(MachineInstr &I, MachineRegisterInfo &MRI) const;
bool selectExtractElt(MachineInstr &I, MachineRegisterInfo &MRI) const; bool selectExtractElt(MachineInstr &I, MachineRegisterInfo &MRI) const;
bool selectConcatVectors(MachineInstr &I, MachineRegisterInfo &MRI) const; bool selectConcatVectors(MachineInstr &I, MachineRegisterInfo &MRI) const;
@ -3065,29 +3063,6 @@ bool AArch64InstructionSelector::selectConcatVectors(
return true; return true;
} }
void AArch64InstructionSelector::collectShuffleMaskIndices(
MachineInstr &I, MachineRegisterInfo &MRI,
SmallVectorImpl<Optional<int>> &Idxs) const {
MachineInstr *MaskDef = MRI.getVRegDef(I.getOperand(3).getReg());
assert(
MaskDef->getOpcode() == TargetOpcode::G_BUILD_VECTOR &&
"G_SHUFFLE_VECTOR should have a constant mask operand as G_BUILD_VECTOR");
// Find the constant indices.
for (unsigned i = 1, e = MaskDef->getNumOperands(); i < e; ++i) {
// Look through copies.
MachineInstr *ScalarDef =
getDefIgnoringCopies(MaskDef->getOperand(i).getReg(), MRI);
assert(ScalarDef && "Could not find vreg def of shufflevec index op");
if (ScalarDef->getOpcode() != TargetOpcode::G_CONSTANT) {
// This be an undef if not a constant.
assert(ScalarDef->getOpcode() == TargetOpcode::G_IMPLICIT_DEF);
Idxs.push_back(None);
} else {
Idxs.push_back(ScalarDef->getOperand(1).getCImm()->getSExtValue());
}
}
}
unsigned unsigned
AArch64InstructionSelector::emitConstantPoolEntry(Constant *CPVal, AArch64InstructionSelector::emitConstantPoolEntry(Constant *CPVal,
MachineFunction &MF) const { MachineFunction &MF) const {
@ -3630,16 +3605,9 @@ bool AArch64InstructionSelector::tryOptVectorDup(MachineInstr &I) const {
return false; return false;
// The shuffle's second operand doesn't matter if the mask is all zero. // The shuffle's second operand doesn't matter if the mask is all zero.
auto *ZeroVec = getOpcodeDef(G_BUILD_VECTOR, I.getOperand(3).getReg(), MRI); const Constant *Mask = I.getOperand(3).getShuffleMask();
if (!ZeroVec) if (!isa<ConstantAggregateZero>(Mask))
return false; return false;
int64_t Zero = 0;
if (!mi_match(ZeroVec->getOperand(1).getReg(), MRI, m_ICst(Zero)) || Zero)
return false;
for (unsigned i = 1, e = ZeroVec->getNumOperands(); i < e; ++i) {
if (ZeroVec->getOperand(i).getReg() != ZeroVec->getOperand(1).getReg())
return false; // This wasn't an all zeros vector.
}
// We're done, now find out what kind of splat we need. // We're done, now find out what kind of splat we need.
LLT VecTy = MRI.getType(I.getOperand(0).getReg()); LLT VecTy = MRI.getType(I.getOperand(0).getReg());
@ -3687,19 +3655,14 @@ bool AArch64InstructionSelector::selectShuffleVector(
const LLT Src1Ty = MRI.getType(Src1Reg); const LLT Src1Ty = MRI.getType(Src1Reg);
Register Src2Reg = I.getOperand(2).getReg(); Register Src2Reg = I.getOperand(2).getReg();
const LLT Src2Ty = MRI.getType(Src2Reg); const LLT Src2Ty = MRI.getType(Src2Reg);
const Constant *ShuffleMask = I.getOperand(3).getShuffleMask();
MachineBasicBlock &MBB = *I.getParent(); MachineBasicBlock &MBB = *I.getParent();
MachineFunction &MF = *MBB.getParent(); MachineFunction &MF = *MBB.getParent();
LLVMContext &Ctx = MF.getFunction().getContext(); LLVMContext &Ctx = MF.getFunction().getContext();
// G_SHUFFLE_VECTOR doesn't really have a strictly enforced constant mask SmallVector<int, 8> Mask;
// operand, it comes in as a normal vector value which we have to analyze to ShuffleVectorInst::getShuffleMask(ShuffleMask, Mask);
// find the mask indices. If the mask element is undef, then
// collectShuffleMaskIndices() will add a None entry for that index into
// the list.
SmallVector<Optional<int>, 8> Mask;
collectShuffleMaskIndices(I, MRI, Mask);
assert(!Mask.empty() && "Expected to find mask indices");
// G_SHUFFLE_VECTOR is weird in that the source operands can be scalars, if // G_SHUFFLE_VECTOR is weird in that the source operands can be scalars, if
// it's originated from a <1 x T> type. Those should have been lowered into // it's originated from a <1 x T> type. Those should have been lowered into
@ -3712,10 +3675,10 @@ bool AArch64InstructionSelector::selectShuffleVector(
unsigned BytesPerElt = DstTy.getElementType().getSizeInBits() / 8; unsigned BytesPerElt = DstTy.getElementType().getSizeInBits() / 8;
SmallVector<Constant *, 64> CstIdxs; SmallVector<Constant *, 64> CstIdxs;
for (auto &MaybeVal : Mask) { for (int Val : Mask) {
// For now, any undef indexes we'll just assume to be 0. This should be // For now, any undef indexes we'll just assume to be 0. This should be
// optimized in future, e.g. to select DUP etc. // optimized in future, e.g. to select DUP etc.
int Val = MaybeVal.hasValue() ? *MaybeVal : 0; Val = Val < 0 ? 0 : Val;
for (unsigned Byte = 0; Byte < BytesPerElt; ++Byte) { for (unsigned Byte = 0; Byte < BytesPerElt; ++Byte) {
unsigned Offset = Byte + Val * BytesPerElt; unsigned Offset = Byte + Val * BytesPerElt;
CstIdxs.emplace_back(ConstantInt::get(Type::getInt8Ty(Ctx), Offset)); CstIdxs.emplace_back(ConstantInt::get(Type::getInt8Ty(Ctx), Offset));

View File

@ -789,6 +789,7 @@ static bool IsAnAddressOperand(const MachineOperand &MO) {
case MachineOperand::MO_Immediate: case MachineOperand::MO_Immediate:
case MachineOperand::MO_CImmediate: case MachineOperand::MO_CImmediate:
case MachineOperand::MO_FPImmediate: case MachineOperand::MO_FPImmediate:
case MachineOperand::MO_ShuffleMask:
return false; return false;
case MachineOperand::MO_MachineBasicBlock: case MachineOperand::MO_MachineBasicBlock:
return true; return true;

View File

@ -1622,9 +1622,7 @@ define <2 x i32> @test_shufflevector_s32_v2s32(i32 %arg) {
; CHECK-LABEL: name: test_shufflevector_s32_v2s32 ; CHECK-LABEL: name: test_shufflevector_s32_v2s32
; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0
; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], shufflemask(0, 0)
; CHECK-DAG: [[MASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C0]](s32), [[C0]](s32)
; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], [[MASK]](<2 x s32>)
; CHECK: $d0 = COPY [[VEC]](<2 x s32>) ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
%vec = insertelement <1 x i32> undef, i32 %arg, i32 0 %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
%res = shufflevector <1 x i32> %vec, <1 x i32> undef, <2 x i32> zeroinitializer %res = shufflevector <1 x i32> %vec, <1 x i32> undef, <2 x i32> zeroinitializer
@ -1634,25 +1632,40 @@ define <2 x i32> @test_shufflevector_s32_v2s32(i32 %arg) {
define i32 @test_shufflevector_v2s32_s32(<2 x i32> %arg) { define i32 @test_shufflevector_v2s32_s32(<2 x i32> %arg) {
; CHECK-LABEL: name: test_shufflevector_v2s32_s32 ; CHECK-LABEL: name: test_shufflevector_v2s32_s32
; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(1)
; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK: [[RES:%[0-9]+]]:_(s32) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], [[C1]](s32)
; CHECK: $w0 = COPY [[RES]](s32) ; CHECK: $w0 = COPY [[RES]](s32)
%vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <1 x i32> <i32 1> %vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <1 x i32> <i32 1>
%res = extractelement <1 x i32> %vec, i32 0 %res = extractelement <1 x i32> %vec, i32 0
ret i32 %res ret i32 %res
} }
define <2 x i32> @test_shufflevector_v2s32_v2s32(<2 x i32> %arg) { define <2 x i32> @test_shufflevector_v2s32_v2s32_undef(<2 x i32> %arg) {
; CHECK-LABEL: name: test_shufflevector_v2s32_v2s32 ; CHECK-LABEL: name: test_shufflevector_v2s32_v2s32_undef
; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(undef, undef)
; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
; CHECK-DAG: [[MASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C0]](s32)
; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], [[MASK]](<2 x s32>)
; CHECK: $d0 = COPY [[VEC]](<2 x s32>) ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
%res = shufflevector <2 x i32> %arg, <2 x i32> undef, <2 x i32> <i32 1, i32 0> %res = shufflevector <2 x i32> %arg, <2 x i32> undef, <2 x i32> undef
ret <2 x i32> %res
}
define <2 x i32> @test_shufflevector_v2s32_v2s32_undef_0(<2 x i32> %arg) {
; CHECK-LABEL: name: test_shufflevector_v2s32_v2s32_undef_0
; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(undef, 0)
; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
%res = shufflevector <2 x i32> %arg, <2 x i32> undef, <2 x i32> <i32 undef, i32 0>
ret <2 x i32> %res
}
define <2 x i32> @test_shufflevector_v2s32_v2s32_0_undef(<2 x i32> %arg) {
; CHECK-LABEL: name: test_shufflevector_v2s32_v2s32_0_undef
; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(0, undef)
; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
%res = shufflevector <2 x i32> %arg, <2 x i32> undef, <2 x i32> <i32 0, i32 undef>
ret <2 x i32> %res ret <2 x i32> %res
} }
@ -1660,10 +1673,7 @@ define i32 @test_shufflevector_v2s32_v3s32(<2 x i32> %arg) {
; CHECK-LABEL: name: test_shufflevector_v2s32_v3s32 ; CHECK-LABEL: name: test_shufflevector_v2s32_v3s32
; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 ; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(1, 0, 1)
; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
; CHECK-DAG: [[MASK:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C0]](s32), [[C1]](s32)
; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], [[MASK]](<3 x s32>)
; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>) ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
%vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <3 x i32> <i32 1, i32 0, i32 1> %vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <3 x i32> <i32 1, i32 0, i32 1>
%res = extractelement <3 x i32> %vec, i32 0 %res = extractelement <3 x i32> %vec, i32 0
@ -1674,12 +1684,7 @@ define <4 x i32> @test_shufflevector_v2s32_v4s32(<2 x i32> %arg1, <2 x i32> %arg
; CHECK-LABEL: name: test_shufflevector_v2s32_v4s32 ; CHECK-LABEL: name: test_shufflevector_v2s32_v4s32
; CHECK: [[ARG1:%[0-9]+]]:_(<2 x s32>) = COPY $d0 ; CHECK: [[ARG1:%[0-9]+]]:_(<2 x s32>) = COPY $d0
; CHECK: [[ARG2:%[0-9]+]]:_(<2 x s32>) = COPY $d1 ; CHECK: [[ARG2:%[0-9]+]]:_(<2 x s32>) = COPY $d1
; CHECK: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 ; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[ARG1]](<2 x s32>), [[ARG2]], shufflemask(0, 1, 2, 3)
; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
; CHECK: [[MASK:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C0]](s32), [[C1]](s32), [[C2]](s32), [[C3]](s32)
; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[ARG1]](<2 x s32>), [[ARG2]], [[MASK]](<4 x s32>)
; CHECK: $q0 = COPY [[VEC]](<4 x s32>) ; CHECK: $q0 = COPY [[VEC]](<4 x s32>)
%res = shufflevector <2 x i32> %arg1, <2 x i32> %arg2, <4 x i32> <i32 0, i32 1, i32 2, i32 3> %res = shufflevector <2 x i32> %arg1, <2 x i32> %arg2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
ret <4 x i32> %res ret <4 x i32> %res
@ -1689,10 +1694,7 @@ define <2 x i32> @test_shufflevector_v4s32_v2s32(<4 x i32> %arg) {
; CHECK-LABEL: name: test_shufflevector_v4s32_v2s32 ; CHECK-LABEL: name: test_shufflevector_v4s32_v2s32
; CHECK: [[ARG:%[0-9]+]]:_(<4 x s32>) = COPY $q0 ; CHECK: [[ARG:%[0-9]+]]:_(<4 x s32>) = COPY $q0
; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF
; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<4 x s32>), [[UNDEF]], shufflemask(1, 3)
; CHECK-DAG: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
; CHECK-DAG: [[MASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C3]](s32)
; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<4 x s32>), [[UNDEF]], [[MASK]](<2 x s32>)
; CHECK: $d0 = COPY [[VEC]](<2 x s32>) ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
%res = shufflevector <4 x i32> %arg, <4 x i32> undef, <2 x i32> <i32 1, i32 3> %res = shufflevector <4 x i32> %arg, <4 x i32> undef, <2 x i32> <i32 1, i32 3>
ret <2 x i32> %res ret <2 x i32> %res
@ -1703,24 +1705,7 @@ define <16 x i8> @test_shufflevector_v8s8_v16s8(<8 x i8> %arg1, <8 x i8> %arg2)
; CHECK-LABEL: name: test_shufflevector_v8s8_v16s8 ; CHECK-LABEL: name: test_shufflevector_v8s8_v16s8
; CHECK: [[ARG1:%[0-9]+]]:_(<8 x s8>) = COPY $d0 ; CHECK: [[ARG1:%[0-9]+]]:_(<8 x s8>) = COPY $d0
; CHECK: [[ARG2:%[0-9]+]]:_(<8 x s8>) = COPY $d1 ; CHECK: [[ARG2:%[0-9]+]]:_(<8 x s8>) = COPY $d1
; CHECK: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 ; CHECK: [[VEC:%[0-9]+]]:_(<16 x s8>) = G_SHUFFLE_VECTOR [[ARG1]](<8 x s8>), [[ARG2]], shufflemask(0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15)
; CHECK: [[C8:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK: [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 9
; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
; CHECK: [[C10:%[0-9]+]]:_(s32) = G_CONSTANT i32 10
; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
; CHECK: [[C11:%[0-9]+]]:_(s32) = G_CONSTANT i32 11
; CHECK: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
; CHECK: [[C12:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
; CHECK: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
; CHECK: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
; CHECK: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 6
; CHECK: [[C14:%[0-9]+]]:_(s32) = G_CONSTANT i32 14
; CHECK: [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 7
; CHECK: [[C15:%[0-9]+]]:_(s32) = G_CONSTANT i32 15
; CHECK: [[MASK:%[0-9]+]]:_(<16 x s32>) = G_BUILD_VECTOR [[C0]](s32), [[C8]](s32), [[C1]](s32), [[C9]](s32), [[C2]](s32), [[C10]](s32), [[C3]](s32), [[C11]](s32), [[C4]](s32), [[C12]](s32), [[C5]](s32), [[C13]](s32), [[C6]](s32), [[C14]](s32), [[C7]](s32), [[C15]](s32)
; CHECK: [[VEC:%[0-9]+]]:_(<16 x s8>) = G_SHUFFLE_VECTOR [[ARG1]](<8 x s8>), [[ARG2]], [[MASK]](<16 x s32>)
; CHECK: $q0 = COPY [[VEC]](<16 x s8>) ; CHECK: $q0 = COPY [[VEC]](<16 x s8>)
%res = shufflevector <8 x i8> %arg1, <8 x i8> %arg2, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15> %res = shufflevector <8 x i8> %arg1, <8 x i8> %arg2, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15>
ret <16 x i8> %res ret <16 x i8> %res

View File

@ -12,16 +12,12 @@ body: |
; CHECK: liveins: $q0, $q1 ; CHECK: liveins: $q0, $q1
; CHECK: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 ; CHECK: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0
; CHECK: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 ; CHECK: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 ; CHECK: [[SHUF:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[COPY]](<4 x s32>), [[COPY1]], shufflemask(0, 0, 0, 0)
; CHECK: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
; CHECK: [[SHUF:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[COPY]](<4 x s32>), [[COPY1]], [[BUILD_VECTOR]](<4 x s32>)
; CHECK: $q0 = COPY [[SHUF]](<4 x s32>) ; CHECK: $q0 = COPY [[SHUF]](<4 x s32>)
; CHECK: RET_ReallyLR implicit $q0 ; CHECK: RET_ReallyLR implicit $q0
%0:_(<4 x s32>) = COPY $q0 %0:_(<4 x s32>) = COPY $q0
%1:_(<4 x s32>) = COPY $q1 %1:_(<4 x s32>) = COPY $q1
%4:_(s32) = G_CONSTANT i32 0 %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(0, 0, 0, 0)
%3:_(<4 x s32>) = G_BUILD_VECTOR %4(s32), %4(s32), %4(s32), %4(s32)
%2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, %3(<4 x s32>)
$q0 = COPY %2(<4 x s32>) $q0 = COPY %2(<4 x s32>)
RET_ReallyLR implicit $q0 RET_ReallyLR implicit $q0
@ -38,16 +34,12 @@ body: |
; CHECK: liveins: $q0, $q1 ; CHECK: liveins: $q0, $q1
; CHECK: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 ; CHECK: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
; CHECK: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1 ; CHECK: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 ; CHECK: [[SHUF:%[0-9]+]]:_(<2 x s64>) = G_SHUFFLE_VECTOR [[COPY]](<2 x s64>), [[COPY1]], shufflemask(0, 0)
; CHECK: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32)
; CHECK: [[SHUF:%[0-9]+]]:_(<2 x s64>) = G_SHUFFLE_VECTOR [[COPY]](<2 x s64>), [[COPY1]], [[BUILD_VECTOR]](<2 x s32>)
; CHECK: $q0 = COPY [[SHUF]](<2 x s64>) ; CHECK: $q0 = COPY [[SHUF]](<2 x s64>)
; CHECK: RET_ReallyLR implicit $q0 ; CHECK: RET_ReallyLR implicit $q0
%0:_(<2 x s64>) = COPY $q0 %0:_(<2 x s64>) = COPY $q0
%1:_(<2 x s64>) = COPY $q1 %1:_(<2 x s64>) = COPY $q1
%4:_(s32) = G_CONSTANT i32 0 %2:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %1, shufflemask(0, 0)
%3:_(<2 x s32>) = G_BUILD_VECTOR %4(s32), %4(s32)
%2:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %1, %3(<2 x s32>)
$q0 = COPY %2(<2 x s64>) $q0 = COPY %2(<2 x s64>)
RET_ReallyLR implicit $q0 RET_ReallyLR implicit $q0

View File

@ -424,7 +424,7 @@
# DEBUG-NEXT: G_EXTRACT_VECTOR_ELT (opcode {{[0-9]+}}): 3 type indices, 0 imm indices # DEBUG-NEXT: G_EXTRACT_VECTOR_ELT (opcode {{[0-9]+}}): 3 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected # DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected # DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_SHUFFLE_VECTOR (opcode {{[0-9]+}}): 3 type indices, 0 imm indices # DEBUG-NEXT: G_SHUFFLE_VECTOR (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected # DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected # DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_CTTZ (opcode {{[0-9]+}}): 2 type indices, 0 imm indices # DEBUG-NEXT: G_CTTZ (opcode {{[0-9]+}}): 2 type indices, 0 imm indices

View File

@ -19,9 +19,8 @@ body: |
%0:gpr(s32) = COPY $w0 %0:gpr(s32) = COPY $w0
%2:fpr(<4 x s32>) = G_IMPLICIT_DEF %2:fpr(<4 x s32>) = G_IMPLICIT_DEF
%3:gpr(s32) = G_CONSTANT i32 0 %3:gpr(s32) = G_CONSTANT i32 0
%5:fpr(<4 x s32>) = G_BUILD_VECTOR %3(s32), %3(s32), %3(s32), %3(s32)
%1:fpr(<4 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s32) %1:fpr(<4 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s32)
%4:fpr(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, %5(<4 x s32>) %4:fpr(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, shufflemask(0, 0, 0, 0)
$q0 = COPY %4(<4 x s32>) $q0 = COPY %4(<4 x s32>)
RET_ReallyLR implicit $q0 RET_ReallyLR implicit $q0
@ -45,9 +44,8 @@ body: |
%0:gpr(s64) = COPY $x0 %0:gpr(s64) = COPY $x0
%2:fpr(<2 x s64>) = G_IMPLICIT_DEF %2:fpr(<2 x s64>) = G_IMPLICIT_DEF
%3:gpr(s32) = G_CONSTANT i32 0 %3:gpr(s32) = G_CONSTANT i32 0
%5:fpr(<2 x s32>) = G_BUILD_VECTOR %3(s32), %3(s32)
%1:fpr(<2 x s64>) = G_INSERT_VECTOR_ELT %2, %0(s64), %3(s32) %1:fpr(<2 x s64>) = G_INSERT_VECTOR_ELT %2, %0(s64), %3(s32)
%4:fpr(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, %5(<2 x s32>) %4:fpr(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, shufflemask(0, 0)
$q0 = COPY %4(<2 x s64>) $q0 = COPY %4(<2 x s64>)
RET_ReallyLR implicit $q0 RET_ReallyLR implicit $q0
@ -73,9 +71,8 @@ body: |
%0:fpr(s32) = COPY $s0 %0:fpr(s32) = COPY $s0
%2:fpr(<4 x s32>) = G_IMPLICIT_DEF %2:fpr(<4 x s32>) = G_IMPLICIT_DEF
%3:gpr(s32) = G_CONSTANT i32 0 %3:gpr(s32) = G_CONSTANT i32 0
%5:fpr(<4 x s32>) = G_BUILD_VECTOR %3(s32), %3(s32), %3(s32), %3(s32)
%1:fpr(<4 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s32) %1:fpr(<4 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s32)
%4:fpr(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, %5(<4 x s32>) %4:fpr(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, shufflemask(0, 0, 0, 0)
$q0 = COPY %4(<4 x s32>) $q0 = COPY %4(<4 x s32>)
RET_ReallyLR implicit $q0 RET_ReallyLR implicit $q0
@ -101,9 +98,8 @@ body: |
%0:fpr(s64) = COPY $d0 %0:fpr(s64) = COPY $d0
%2:fpr(<2 x s64>) = G_IMPLICIT_DEF %2:fpr(<2 x s64>) = G_IMPLICIT_DEF
%3:gpr(s32) = G_CONSTANT i32 0 %3:gpr(s32) = G_CONSTANT i32 0
%5:fpr(<2 x s32>) = G_BUILD_VECTOR %3(s32), %3(s32)
%1:fpr(<2 x s64>) = G_INSERT_VECTOR_ELT %2, %0(s64), %3(s32) %1:fpr(<2 x s64>) = G_INSERT_VECTOR_ELT %2, %0(s64), %3(s32)
%4:fpr(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, %5(<2 x s32>) %4:fpr(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, shufflemask(0, 0)
$q0 = COPY %4(<2 x s64>) $q0 = COPY %4(<2 x s64>)
RET_ReallyLR implicit $q0 RET_ReallyLR implicit $q0
@ -132,10 +128,9 @@ body: |
%2:fpr(<2 x s64>) = G_IMPLICIT_DEF %2:fpr(<2 x s64>) = G_IMPLICIT_DEF
%6:fpr(<2 x s64>) = COPY %2 %6:fpr(<2 x s64>) = COPY %2
%3:gpr(s32) = G_CONSTANT i32 0 %3:gpr(s32) = G_CONSTANT i32 0
%5:fpr(<2 x s32>) = G_BUILD_VECTOR %3(s32), %3(s32)
%1:fpr(<2 x s64>) = G_INSERT_VECTOR_ELT %6, %0(s64), %3(s32) %1:fpr(<2 x s64>) = G_INSERT_VECTOR_ELT %6, %0(s64), %3(s32)
%7:fpr(<2 x s64>) = COPY %1 %7:fpr(<2 x s64>) = COPY %1
%4:fpr(<2 x s64>) = G_SHUFFLE_VECTOR %7(<2 x s64>), %2, %5(<2 x s32>) %4:fpr(<2 x s64>) = G_SHUFFLE_VECTOR %7(<2 x s64>), %2, shufflemask(0, 0)
$q0 = COPY %4(<2 x s64>) $q0 = COPY %4(<2 x s64>)
RET_ReallyLR implicit $q0 RET_ReallyLR implicit $q0
@ -164,9 +159,7 @@ body: |
%0:gpr(s64) = COPY $x0 %0:gpr(s64) = COPY $x0
%2:fpr(<2 x s64>) = G_IMPLICIT_DEF %2:fpr(<2 x s64>) = G_IMPLICIT_DEF
%3:gpr(s32) = G_CONSTANT i32 0 %3:gpr(s32) = G_CONSTANT i32 0
%6:gpr(s32) = G_CONSTANT i32 1
%5:fpr(<2 x s32>) = G_BUILD_VECTOR %3(s32), %6(s32)
%1:fpr(<2 x s64>) = G_INSERT_VECTOR_ELT %2, %0(s64), %3(s32) %1:fpr(<2 x s64>) = G_INSERT_VECTOR_ELT %2, %0(s64), %3(s32)
%4:fpr(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, %5(<2 x s32>) %4:fpr(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, shufflemask(0, 1)
$q0 = COPY %4(<2 x s64>) $q0 = COPY %4(<2 x s64>)
RET_ReallyLR implicit $q0 RET_ReallyLR implicit $q0

View File

@ -61,10 +61,7 @@ body: |
; CHECK: RET_ReallyLR implicit $d0 ; CHECK: RET_ReallyLR implicit $d0
%0:fpr(<2 x s32>) = COPY $d0 %0:fpr(<2 x s32>) = COPY $d0
%1:fpr(<2 x s32>) = COPY $d1 %1:fpr(<2 x s32>) = COPY $d1
%4:gpr(s32) = G_CONSTANT i32 1 %2:fpr(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1, 0)
%5:gpr(s32) = G_CONSTANT i32 0
%3:fpr(<2 x s32>) = G_BUILD_VECTOR %4(s32), %5(s32)
%2:fpr(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, %3(<2 x s32>)
$d0 = COPY %2(<2 x s32>) $d0 = COPY %2(<2 x s32>)
RET_ReallyLR implicit $d0 RET_ReallyLR implicit $d0
@ -95,11 +92,7 @@ body: |
; CHECK: RET_ReallyLR implicit $q0 ; CHECK: RET_ReallyLR implicit $q0
%0:fpr(<4 x s32>) = COPY $q0 %0:fpr(<4 x s32>) = COPY $q0
%1:fpr(<4 x s32>) = COPY $q1 %1:fpr(<4 x s32>) = COPY $q1
%4:gpr(s32) = G_CONSTANT i32 0 %2:fpr(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(0, 1, 3, 0)
%5:gpr(s32) = G_CONSTANT i32 1
%6:gpr(s32) = G_CONSTANT i32 3
%3:fpr(<4 x s32>) = G_BUILD_VECTOR %4(s32), %5(s32), %6(s32), %4(s32)
%2:fpr(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, %3(<4 x s32>)
$q0 = COPY %2(<4 x s32>) $q0 = COPY %2(<4 x s32>)
RET_ReallyLR implicit $q0 RET_ReallyLR implicit $q0
@ -130,12 +123,7 @@ body: |
; CHECK: RET_ReallyLR implicit $q0 ; CHECK: RET_ReallyLR implicit $q0
%0:fpr(<4 x s32>) = COPY $q0 %0:fpr(<4 x s32>) = COPY $q0
%1:fpr(<4 x s32>) = COPY $q1 %1:fpr(<4 x s32>) = COPY $q1
%4:gpr(s32) = G_CONSTANT i32 5 %2:fpr(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(5, 7, 1, 0)
%5:gpr(s32) = G_CONSTANT i32 7
%6:gpr(s32) = G_CONSTANT i32 1
%7:gpr(s32) = G_CONSTANT i32 0
%3:fpr(<4 x s32>) = G_BUILD_VECTOR %4(s32), %5(s32), %6(s32), %7(s32)
%2:fpr(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, %3(<4 x s32>)
$q0 = COPY %2(<4 x s32>) $q0 = COPY %2(<4 x s32>)
RET_ReallyLR implicit $q0 RET_ReallyLR implicit $q0
@ -166,9 +154,7 @@ body: |
; CHECK: RET_ReallyLR implicit $q0 ; CHECK: RET_ReallyLR implicit $q0
%0:fpr(<2 x s64>) = COPY $q0 %0:fpr(<2 x s64>) = COPY $q0
%1:fpr(<2 x s64>) = COPY $q1 %1:fpr(<2 x s64>) = COPY $q1
%4:gpr(s32) = G_CONSTANT i32 0 %2:fpr(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %1, shufflemask(0, 0)
%3:fpr(<2 x s32>) = G_BUILD_VECTOR %4(s32), %4(s32)
%2:fpr(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %1, %3(<2 x s32>)
$q0 = COPY %2(<2 x s64>) $q0 = COPY %2(<2 x s64>)
RET_ReallyLR implicit $q0 RET_ReallyLR implicit $q0

View File

@ -41,10 +41,7 @@ body: |
%6:gpr(s32) = G_IMPLICIT_DEF %6:gpr(s32) = G_IMPLICIT_DEF
%7:gpr(s32) = G_IMPLICIT_DEF %7:gpr(s32) = G_IMPLICIT_DEF
%2:fpr(<2 x s32>) = G_BUILD_VECTOR %6(s32), %7(s32) %2:fpr(<2 x s32>) = G_BUILD_VECTOR %6(s32), %7(s32)
%4:gpr(s32) = G_CONSTANT i32 1 %1:fpr(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(1, undef)
%5:gpr(s32) = G_IMPLICIT_DEF
%3:fpr(<2 x s32>) = G_BUILD_VECTOR %4(s32), %5(s32)
%1:fpr(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, %3(<2 x s32>)
$d0 = COPY %1(<2 x s32>) $d0 = COPY %1(<2 x s32>)
RET_ReallyLR implicit $d0 RET_ReallyLR implicit $d0

View File

@ -438,9 +438,7 @@ define i32 @test_shufflevector_s32_v2s32(i32 %arg) {
; CHECK-LABEL: name: test_shufflevector_s32_v2s32 ; CHECK-LABEL: name: test_shufflevector_s32_v2s32
; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $r0 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $r0
; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], shufflemask(0, 0)
; CHECK-DAG: [[MASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C0]](s32), [[C0]](s32)
; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], [[MASK]](<2 x s32>)
; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>) ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>)
%vec = insertelement <1 x i32> undef, i32 %arg, i32 0 %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
%shuffle = shufflevector <1 x i32> %vec, <1 x i32> undef, <2 x i32> zeroinitializer %shuffle = shufflevector <1 x i32> %vec, <1 x i32> undef, <2 x i32> zeroinitializer
@ -455,10 +453,9 @@ define i32 @test_shufflevector_v2s32_v3s32(i32 %arg1, i32 %arg2) {
; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 ; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 ; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK-DAG: [[MASK:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C0]](s32), [[C1]](s32)
; CHECK-DAG: [[V1:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[UNDEF]], [[ARG1]](s32), [[C0]](s32) ; CHECK-DAG: [[V1:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[UNDEF]], [[ARG1]](s32), [[C0]](s32)
; CHECK-DAG: [[V2:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[V1]], [[ARG2]](s32), [[C1]](s32) ; CHECK-DAG: [[V2:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[V1]], [[ARG2]](s32), [[C1]](s32)
; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_SHUFFLE_VECTOR [[V2]](<2 x s32>), [[UNDEF]], [[MASK]](<3 x s32>) ; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_SHUFFLE_VECTOR [[V2]](<2 x s32>), [[UNDEF]], shufflemask(1, 0, 1)
; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>) ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
%v1 = insertelement <2 x i32> undef, i32 %arg1, i32 0 %v1 = insertelement <2 x i32> undef, i32 %arg1, i32 0
%v2 = insertelement <2 x i32> %v1, i32 %arg2, i32 1 %v2 = insertelement <2 x i32> %v1, i32 %arg2, i32 1
@ -475,10 +472,9 @@ define i32 @test_shufflevector_v2s32_v4s32(i32 %arg1, i32 %arg2) {
; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 ; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 ; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK-DAG: [[MASK:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C0]](s32), [[C0]](s32), [[C0]](s32), [[C0]](s32)
; CHECK-DAG: [[V1:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[UNDEF]], [[ARG1]](s32), [[C0]](s32) ; CHECK-DAG: [[V1:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[UNDEF]], [[ARG1]](s32), [[C0]](s32)
; CHECK-DAG: [[V2:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[V1]], [[ARG2]](s32), [[C1]](s32) ; CHECK-DAG: [[V2:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[V1]], [[ARG2]](s32), [[C1]](s32)
; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[V2]](<2 x s32>), [[UNDEF]], [[MASK]](<4 x s32>) ; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[V2]](<2 x s32>), [[UNDEF]], shufflemask(0, 0, 0, 0)
; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<4 x s32>) ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<4 x s32>)
%v1 = insertelement <2 x i32> undef, i32 %arg1, i32 0 %v1 = insertelement <2 x i32> undef, i32 %arg1, i32 0
%v2 = insertelement <2 x i32> %v1, i32 %arg2, i32 1 %v2 = insertelement <2 x i32> %v1, i32 %arg2, i32 1
@ -498,12 +494,11 @@ define i32 @test_shufflevector_v4s32_v2s32(i32 %arg1, i32 %arg2, i32 %arg3, i32
; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 ; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK-DAG: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2 ; CHECK-DAG: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
; CHECK-DAG: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3 ; CHECK-DAG: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
; CHECK-DAG: [[MASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C3]](s32)
; CHECK-DAG: [[V1:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[UNDEF]], [[ARG1]](s32), [[C0]](s32) ; CHECK-DAG: [[V1:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[UNDEF]], [[ARG1]](s32), [[C0]](s32)
; CHECK-DAG: [[V2:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[V1]], [[ARG2]](s32), [[C1]](s32) ; CHECK-DAG: [[V2:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[V1]], [[ARG2]](s32), [[C1]](s32)
; CHECK-DAG: [[V3:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[V2]], [[ARG3]](s32), [[C2]](s32) ; CHECK-DAG: [[V3:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[V2]], [[ARG3]](s32), [[C2]](s32)
; CHECK-DAG: [[V4:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[V3]], [[ARG4]](s32), [[C3]](s32) ; CHECK-DAG: [[V4:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[V3]], [[ARG4]](s32), [[C3]](s32)
; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[V4]](<4 x s32>), [[UNDEF]], [[MASK]](<2 x s32>) ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[V4]](<4 x s32>), [[UNDEF]], shufflemask(1, 3)
; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>) ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>)
%v1 = insertelement <4 x i32> undef, i32 %arg1, i32 0 %v1 = insertelement <4 x i32> undef, i32 %arg1, i32 0
%v2 = insertelement <4 x i32> %v1, i32 %arg2, i32 1 %v2 = insertelement <4 x i32> %v1, i32 %arg2, i32 1

View File

@ -0,0 +1,19 @@
# RUN: not llc -mtriple=aarch64-- -run-pass=none -o /dev/null %s 2>&1 | FileCheck %s
---
name: test_missing_comma
tracksRegLiveness: true
body: |
bb.0:
liveins: $d0
%0:_(<2 x s32>) = COPY $d0
%2:_(<2 x s32>) = G_IMPLICIT_DEF
; FIXME: Not ideal error
; CHECK: [[@LINE+1]]:73: shufflemask should be terminated by ')'.
%1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(1 0)
$d0 = COPY %1(<2 x s32>)
RET_ReallyLR implicit $d0
...

View File

@ -0,0 +1,18 @@
# RUN: not llc -mtriple=aarch64-- -run-pass=none -o /dev/null %s 2>&1 | FileCheck %s
---
name: test_missing_lparen
tracksRegLiveness: true
body: |
bb.0:
liveins: $d0
%0:_(<2 x s32>) = COPY $d0
%2:_(<2 x s32>) = G_IMPLICIT_DEF
; CHECK: [[@LINE+1]]:71: expected syntax shufflemask(<integer or undef>, ...)
%1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask 1, 0)
$d0 = COPY %1(<2 x s32>)
RET_ReallyLR implicit $d0
...

View File

@ -0,0 +1,18 @@
# RUN: not llc -mtriple=aarch64-- -run-pass=none -o /dev/null %s 2>&1 | FileCheck %s
---
name: test_missing_rparen
tracksRegLiveness: true
body: |
bb.0:
liveins: $d0
%0:_(<2 x s32>) = COPY $d0
%2:_(<2 x s32>) = G_IMPLICIT_DEF
; CHECK: [[@LINE+1]]:75: shufflemask should be terminated by ')'.
%1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(1, 0
$d0 = COPY %1(<2 x s32>)
RET_ReallyLR implicit $d0
...

View File

@ -0,0 +1,18 @@
# RUN: not llc -mtriple=aarch64-- -run-pass=none -o /dev/null %s 2>&1 | FileCheck %s
---
name: test_not_integer
tracksRegLiveness: true
body: |
bb.0:
liveins: $d0
%0:_(<2 x s32>) = COPY $d0
%2:_(<2 x s32>) = G_IMPLICIT_DEF
; CHECK: [[@LINE+1]]:74: expected integer constant
%1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(1, arst)
$d0 = COPY %1(<2 x s32>)
RET_ReallyLR implicit $d0
...

View File

@ -0,0 +1,175 @@
# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass none -o - %s | FileCheck %s
# This test ensures that the MIR parser parses shufflemask correctly
# CHECK-LABEL: name: test_shuffle_1_0
# CHECK: G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1, 0)
---
name: test_shuffle_1_0
tracksRegLiveness: true
body: |
bb.0:
liveins: $d0
%0:_(<2 x s32>) = COPY $d0
%2:_(<2 x s32>) = G_IMPLICIT_DEF
%1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(1, 0)
$d0 = COPY %1(<2 x s32>)
RET_ReallyLR implicit $d0
...
# CHECK-LABEL: name: test_shuffle_nospace
# CHECK: G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1, 0)
---
name: test_shuffle_nospace
tracksRegLiveness: true
body: |
bb.0:
liveins: $d0
%0:_(<2 x s32>) = COPY $d0
%2:_(<2 x s32>) = G_IMPLICIT_DEF
%1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(1,0)
$d0 = COPY %1(<2 x s32>)
RET_ReallyLR implicit $d0
...
# CHECK-LABEL: name: test_shuffle_0_0
# CHECK: G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(0, 0)
---
name: test_shuffle_0_0
tracksRegLiveness: true
body: |
bb.0:
liveins: $d0
%0:_(<2 x s32>) = COPY $d0
%2:_(<2 x s32>) = G_IMPLICIT_DEF
%1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(0, 0)
$d0 = COPY %1(<2 x s32>)
RET_ReallyLR implicit $d0
...
# CHECK-LABEL: name: test_shuffle_1_1
# CHECK: G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1, 1)
---
name: test_shuffle_1_1
tracksRegLiveness: true
body: |
bb.0:
liveins: $d0
%0:_(<2 x s32>) = COPY $d0
%2:_(<2 x s32>) = G_IMPLICIT_DEF
%1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(1, 1)
$d0 = COPY %1(<2 x s32>)
RET_ReallyLR implicit $d0
...
# CHECK-LABEL: name: test_shuffle_undef_undef
# CHECK: G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(undef, undef)
---
name: test_shuffle_undef_undef
tracksRegLiveness: true
body: |
bb.0:
liveins: $d0
%0:_(<2 x s32>) = COPY $d0
%2:_(<2 x s32>) = G_IMPLICIT_DEF
%1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(undef, undef)
$d0 = COPY %1(<2 x s32>)
RET_ReallyLR implicit $d0
...
# CHECK-LABEL: name: test_shuffle_undef_0
# CHECK: G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(undef, 0)
---
name: test_shuffle_undef_0
tracksRegLiveness: true
body: |
bb.0:
liveins: $d0
%0:_(<2 x s32>) = COPY $d0
%2:_(<2 x s32>) = G_IMPLICIT_DEF
%1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(undef, 0)
$d0 = COPY %1(<2 x s32>)
RET_ReallyLR implicit $d0
...
# CHECK-LABEL: name: test_shuffle_0_undef
# CHECK: G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(0, undef)
---
name: test_shuffle_0_undef
tracksRegLiveness: true
body: |
bb.0:
liveins: $d0
%0:_(<2 x s32>) = COPY $d0
%2:_(<2 x s32>) = G_IMPLICIT_DEF
%1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(0, undef)
$d0 = COPY %1(<2 x s32>)
RET_ReallyLR implicit $d0
...
# CHECK-LABEL: name: test_shuffle_0
# CHECK: G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(0)
---
name: test_shuffle_0
tracksRegLiveness: true
body: |
bb.0:
liveins: $d0
%0:_(<2 x s32>) = COPY $d0
%2:_(<2 x s32>) = G_IMPLICIT_DEF
%1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(0)
$d0 = COPY %1(<2 x s32>)
RET_ReallyLR implicit $d0
...
# CHECK-LABEL: name: test_shuffle_1
# CHECK: G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1)
---
name: test_shuffle_1
tracksRegLiveness: true
body: |
bb.0:
liveins: $d0
%0:_(<2 x s32>) = COPY $d0
%2:_(<2 x s32>) = G_IMPLICIT_DEF
%1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(1)
$d0 = COPY %1(<2 x s32>)
RET_ReallyLR implicit $d0
...
# CHECK-LABEL: name: test_shuffle_undef
# CHECK: G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(undef)
---
name: test_shuffle_undef
tracksRegLiveness: true
body: |
bb.0:
liveins: $d0
%0:_(<2 x s32>) = COPY $d0
%2:_(<2 x s32>) = G_IMPLICIT_DEF
%1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(undef)
$d0 = COPY %1(<2 x s32>)
RET_ReallyLR implicit $d0
...

View File

@ -0,0 +1,29 @@
# RUN: not llc -o - -march=arm64 -global-isel -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s
# REQUIRES: aarch64-registered-target
---
name: g_shuffle_vector
tracksRegLiveness: true
liveins:
body: |
bb.0:
%0:_(<2 x s32>) = G_IMPLICIT_DEF
%1:_(<2 x s32>) = G_IMPLICIT_DEF
%2:_(<4 x s32>) = G_IMPLICIT_DEF
%3:_(s32) = G_CONSTANT i32 0
%4:_(s32) = G_CONSTANT i32 1
%5:_(<2 x s32>) = G_BUILD_VECTOR %3, %4
; CHECK: Bad machine code: Incorrect mask operand type for G_SHUFFLE_VECTOR
%6:_(<4 x s32>) = G_SHUFFLE_VECTOR %0, %1, %2
; CHECK: Bad machine code: Incorrect mask operand type for G_SHUFFLE_VECTOR
%7:_(<4 x s32>) = G_SHUFFLE_VECTOR %0, %1, %5
; CHECK: Bad machine code: Incorrect mask operand type for G_SHUFFLE_VECTOR
%8:_(<4 x s32>) = G_SHUFFLE_VECTOR %0, %1, 0
; CHECK: Bad machine code: Incorrect mask operand type for G_SHUFFLE_VECTOR
%9:_(<4 x s32>) = G_SHUFFLE_VECTOR %0, %1, i32 0
...