mirror of
https://github.com/RPCS3/llvm.git
synced 2026-07-21 03:05:26 -04:00
AMDGPU/R600: Don't use REGISTER_{LOAD,STORE} ISD nodes
This will make transition to SCRATCH_MEMORY easier Differential Revision: https://reviews.llvm.org/D24746 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@291279 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -608,6 +608,10 @@ bool AMDGPUDAGToDAGISel::SelectADDRIndirect(SDValue Addr, SDValue &Base,
|
||||
if ((C = dyn_cast<ConstantSDNode>(Addr))) {
|
||||
Base = CurDAG->getRegister(AMDGPU::INDIRECT_BASE_ADDR, MVT::i32);
|
||||
Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32);
|
||||
} else if ((Addr.getOpcode() == AMDGPUISD::DWORDADDR) &&
|
||||
(C = dyn_cast<ConstantSDNode>(Addr.getOperand(0)))) {
|
||||
Base = CurDAG->getRegister(AMDGPU::INDIRECT_BASE_ADDR, MVT::i32);
|
||||
Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32);
|
||||
} else if ((Addr.getOpcode() == ISD::ADD || Addr.getOpcode() == ISD::OR) &&
|
||||
(C = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))) {
|
||||
Base = Addr.getOperand(0);
|
||||
|
||||
@@ -172,16 +172,6 @@ AMDGPUTargetLowering::AMDGPUTargetLowering(const TargetMachine &TM,
|
||||
setOperationAction(ISD::STORE, MVT::v2f64, Promote);
|
||||
AddPromotedToType(ISD::STORE, MVT::v2f64, MVT::v4i32);
|
||||
|
||||
setTruncStoreAction(MVT::v2i32, MVT::v2i8, Custom);
|
||||
setTruncStoreAction(MVT::v2i32, MVT::v2i16, Custom);
|
||||
|
||||
setTruncStoreAction(MVT::v4i32, MVT::v4i8, Custom);
|
||||
setTruncStoreAction(MVT::v4i32, MVT::v4i16, Expand);
|
||||
|
||||
setTruncStoreAction(MVT::v8i32, MVT::v8i16, Expand);
|
||||
setTruncStoreAction(MVT::v16i32, MVT::v16i8, Expand);
|
||||
setTruncStoreAction(MVT::v16i32, MVT::v16i16, Expand);
|
||||
|
||||
setTruncStoreAction(MVT::i64, MVT::i1, Expand);
|
||||
setTruncStoreAction(MVT::i64, MVT::i8, Expand);
|
||||
setTruncStoreAction(MVT::i64, MVT::i16, Expand);
|
||||
|
||||
@@ -99,6 +99,18 @@ R600TargetLowering::R600TargetLowering(const TargetMachine &TM,
|
||||
|
||||
setTruncStoreAction(MVT::i32, MVT::i8, Custom);
|
||||
setTruncStoreAction(MVT::i32, MVT::i16, Custom);
|
||||
// We need to include these since trunc STORES to PRIVATE need
|
||||
// special handling to accommodate RMW
|
||||
setTruncStoreAction(MVT::v2i32, MVT::v2i16, Custom);
|
||||
setTruncStoreAction(MVT::v4i32, MVT::v4i16, Custom);
|
||||
setTruncStoreAction(MVT::v8i32, MVT::v8i16, Custom);
|
||||
setTruncStoreAction(MVT::v16i32, MVT::v16i16, Custom);
|
||||
setTruncStoreAction(MVT::v32i32, MVT::v32i16, Custom);
|
||||
setTruncStoreAction(MVT::v2i32, MVT::v2i8, Custom);
|
||||
setTruncStoreAction(MVT::v4i32, MVT::v4i8, Custom);
|
||||
setTruncStoreAction(MVT::v8i32, MVT::v8i8, Custom);
|
||||
setTruncStoreAction(MVT::v16i32, MVT::v16i8, Custom);
|
||||
setTruncStoreAction(MVT::v32i32, MVT::v32i8, Custom);
|
||||
|
||||
// Workaround for LegalizeDAG asserting on expansion of i1 vector stores.
|
||||
setTruncStoreAction(MVT::v2i32, MVT::v2i1, Expand);
|
||||
@@ -1087,79 +1099,114 @@ void R600TargetLowering::getStackAddress(unsigned StackWidth,
|
||||
SDValue R600TargetLowering::lowerPrivateTruncStore(StoreSDNode *Store,
|
||||
SelectionDAG &DAG) const {
|
||||
SDLoc DL(Store);
|
||||
//TODO: Who creates the i8 stores?
|
||||
assert(Store->isTruncatingStore()
|
||||
|| Store->getValue().getValueType() == MVT::i8);
|
||||
assert(Store->getAddressSpace() == AMDGPUAS::PRIVATE_ADDRESS);
|
||||
|
||||
unsigned Mask = 0;
|
||||
SDValue Mask;
|
||||
if (Store->getMemoryVT() == MVT::i8) {
|
||||
Mask = 0xff;
|
||||
assert(Store->getAlignment() >= 1);
|
||||
Mask = DAG.getConstant(0xff, DL, MVT::i32);
|
||||
} else if (Store->getMemoryVT() == MVT::i16) {
|
||||
Mask = 0xffff;
|
||||
assert(Store->getAlignment() >= 2);
|
||||
Mask = DAG.getConstant(0xffff, DL, MVT::i32);;
|
||||
} else {
|
||||
llvm_unreachable("Unsupported private trunc store");
|
||||
}
|
||||
|
||||
SDValue Chain = Store->getChain();
|
||||
SDValue BasePtr = Store->getBasePtr();
|
||||
SDValue Offset = Store->getOffset();
|
||||
EVT MemVT = Store->getMemoryVT();
|
||||
|
||||
SDValue Ptr = DAG.getNode(ISD::SRL, DL, MVT::i32, BasePtr,
|
||||
DAG.getConstant(2, DL, MVT::i32));
|
||||
SDValue Dst = DAG.getNode(AMDGPUISD::REGISTER_LOAD, DL, MVT::i32,
|
||||
Chain, Ptr,
|
||||
DAG.getTargetConstant(0, DL, MVT::i32));
|
||||
SDValue LoadPtr = BasePtr;
|
||||
if (!Offset.isUndef()) {
|
||||
LoadPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr, Offset);
|
||||
}
|
||||
|
||||
SDValue ByteIdx = DAG.getNode(ISD::AND, DL, MVT::i32, BasePtr,
|
||||
// Get dword location
|
||||
// TODO: this should be eliminated by the future SHR ptr, 2
|
||||
SDValue Ptr = DAG.getNode(ISD::AND, DL, MVT::i32, LoadPtr,
|
||||
DAG.getConstant(0xfffffffc, DL, MVT::i32));
|
||||
|
||||
// Load dword
|
||||
// TODO: can we be smarter about machine pointer info?
|
||||
SDValue Dst = DAG.getLoad(MVT::i32, DL, Chain, Ptr, MachinePointerInfo());
|
||||
|
||||
Chain = Dst.getValue(1);
|
||||
|
||||
// Get offset in dword
|
||||
SDValue ByteIdx = DAG.getNode(ISD::AND, DL, MVT::i32, LoadPtr,
|
||||
DAG.getConstant(0x3, DL, MVT::i32));
|
||||
|
||||
// Convert byte offset to bit shift
|
||||
SDValue ShiftAmt = DAG.getNode(ISD::SHL, DL, MVT::i32, ByteIdx,
|
||||
DAG.getConstant(3, DL, MVT::i32));
|
||||
|
||||
// TODO: Contrary to the name of the functiom,
|
||||
// it also handles sub i32 non-truncating stores (like i1)
|
||||
SDValue SExtValue = DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i32,
|
||||
Store->getValue());
|
||||
|
||||
// Mask the value to the right type
|
||||
SDValue MaskedValue = DAG.getZeroExtendInReg(SExtValue, DL, MemVT);
|
||||
|
||||
// Shift the value in place
|
||||
SDValue ShiftedValue = DAG.getNode(ISD::SHL, DL, MVT::i32,
|
||||
MaskedValue, ShiftAmt);
|
||||
|
||||
SDValue DstMask = DAG.getNode(ISD::SHL, DL, MVT::i32,
|
||||
DAG.getConstant(Mask, DL, MVT::i32),
|
||||
ShiftAmt);
|
||||
DstMask = DAG.getNode(ISD::XOR, DL, MVT::i32, DstMask,
|
||||
DAG.getConstant(0xffffffff, DL, MVT::i32));
|
||||
// Shift the mask in place
|
||||
SDValue DstMask = DAG.getNode(ISD::SHL, DL, MVT::i32, Mask, ShiftAmt);
|
||||
|
||||
// Invert the mask. NOTE: if we had native ROL instructions we could
|
||||
// use inverted mask
|
||||
DstMask = DAG.getNOT(DL, DstMask, MVT::i32);
|
||||
|
||||
// Cleanup the target bits
|
||||
Dst = DAG.getNode(ISD::AND, DL, MVT::i32, Dst, DstMask);
|
||||
|
||||
// Add the new bits
|
||||
SDValue Value = DAG.getNode(ISD::OR, DL, MVT::i32, Dst, ShiftedValue);
|
||||
return DAG.getNode(AMDGPUISD::REGISTER_STORE, DL, MVT::Other,
|
||||
Chain, Value, Ptr,
|
||||
DAG.getTargetConstant(0, DL, MVT::i32));
|
||||
|
||||
// Store dword
|
||||
// TODO: Can we be smarter about MachinePointerInfo?
|
||||
return DAG.getStore(Chain, DL, Value, Ptr, MachinePointerInfo());
|
||||
}
|
||||
|
||||
SDValue R600TargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG) const {
|
||||
StoreSDNode *StoreNode = cast<StoreSDNode>(Op);
|
||||
unsigned AS = StoreNode->getAddressSpace();
|
||||
SDValue Value = StoreNode->getValue();
|
||||
EVT ValueVT = Value.getValueType();
|
||||
EVT MemVT = StoreNode->getMemoryVT();
|
||||
unsigned Align = StoreNode->getAlignment();
|
||||
|
||||
SDValue Chain = StoreNode->getChain();
|
||||
SDValue Ptr = StoreNode->getBasePtr();
|
||||
SDValue Value = StoreNode->getValue();
|
||||
|
||||
EVT VT = Value.getValueType();
|
||||
EVT MemVT = StoreNode->getMemoryVT();
|
||||
EVT PtrVT = Ptr.getValueType();
|
||||
|
||||
SDLoc DL(Op);
|
||||
|
||||
// Neither LOCAL nor PRIVATE can do vectors at the moment
|
||||
if ((AS == AMDGPUAS::LOCAL_ADDRESS || AS == AMDGPUAS::PRIVATE_ADDRESS) &&
|
||||
ValueVT.isVector()) {
|
||||
return SplitVectorStore(Op, DAG);
|
||||
VT.isVector()) {
|
||||
return scalarizeVectorStore(StoreNode, DAG);
|
||||
}
|
||||
|
||||
// Private AS needs special fixes
|
||||
if (Align < MemVT.getStoreSize() && (AS != AMDGPUAS::PRIVATE_ADDRESS) &&
|
||||
unsigned Align = StoreNode->getAlignment();
|
||||
if (Align < MemVT.getStoreSize() &&
|
||||
!allowsMisalignedMemoryAccesses(MemVT, AS, Align, nullptr)) {
|
||||
return expandUnalignedStore(StoreNode, DAG);
|
||||
}
|
||||
|
||||
SDLoc DL(Op);
|
||||
SDValue Chain = StoreNode->getChain();
|
||||
SDValue Ptr = StoreNode->getBasePtr();
|
||||
SDValue DWordAddr = DAG.getNode(ISD::SRL, DL, PtrVT, Ptr,
|
||||
DAG.getConstant(2, DL, PtrVT));
|
||||
|
||||
if (AS == AMDGPUAS::GLOBAL_ADDRESS) {
|
||||
// It is beneficial to create MSKOR here instead of combiner to avoid
|
||||
// artificial dependencies introduced by RMW
|
||||
if (StoreNode->isTruncatingStore()) {
|
||||
EVT VT = Value.getValueType();
|
||||
assert(VT.bitsLE(MVT::i32));
|
||||
SDValue MaskConstant;
|
||||
if (MemVT == MVT::i8) {
|
||||
@@ -1169,15 +1216,19 @@ SDValue R600TargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG) const {
|
||||
assert(StoreNode->getAlignment() >= 2);
|
||||
MaskConstant = DAG.getConstant(0xFFFF, DL, MVT::i32);
|
||||
}
|
||||
SDValue DWordAddr = DAG.getNode(ISD::SRL, DL, VT, Ptr,
|
||||
DAG.getConstant(2, DL, MVT::i32));
|
||||
SDValue ByteIndex = DAG.getNode(ISD::AND, DL, Ptr.getValueType(), Ptr,
|
||||
DAG.getConstant(0x00000003, DL, VT));
|
||||
|
||||
SDValue ByteIndex = DAG.getNode(ISD::AND, DL, PtrVT, Ptr,
|
||||
DAG.getConstant(0x00000003, DL, PtrVT));
|
||||
SDValue BitShift = DAG.getNode(ISD::SHL, DL, VT, ByteIndex,
|
||||
DAG.getConstant(3, DL, VT));
|
||||
|
||||
// Put the mask in correct place
|
||||
SDValue Mask = DAG.getNode(ISD::SHL, DL, VT, MaskConstant, BitShift);
|
||||
|
||||
// Put the mask in correct place
|
||||
SDValue TruncValue = DAG.getNode(ISD::AND, DL, VT, Value, MaskConstant);
|
||||
SDValue Shift = DAG.getNode(ISD::SHL, DL, VT, ByteIndex,
|
||||
DAG.getConstant(3, DL, VT));
|
||||
SDValue ShiftedValue = DAG.getNode(ISD::SHL, DL, VT, TruncValue, Shift);
|
||||
SDValue Mask = DAG.getNode(ISD::SHL, DL, VT, MaskConstant, Shift);
|
||||
SDValue ShiftedValue = DAG.getNode(ISD::SHL, DL, VT, TruncValue, BitShift);
|
||||
|
||||
// XXX: If we add a 64-bit ZW register class, then we could use a 2 x i32
|
||||
// vector instead.
|
||||
SDValue Src[4] = {
|
||||
@@ -1191,12 +1242,9 @@ SDValue R600TargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG) const {
|
||||
return DAG.getMemIntrinsicNode(AMDGPUISD::STORE_MSKOR, DL,
|
||||
Op->getVTList(), Args, MemVT,
|
||||
StoreNode->getMemOperand());
|
||||
} else if (Ptr->getOpcode() != AMDGPUISD::DWORDADDR &&
|
||||
ValueVT.bitsGE(MVT::i32)) {
|
||||
} else if (Ptr->getOpcode() != AMDGPUISD::DWORDADDR && VT.bitsGE(MVT::i32)) {
|
||||
// Convert pointer from byte address to dword address.
|
||||
Ptr = DAG.getNode(AMDGPUISD::DWORDADDR, DL, Ptr.getValueType(),
|
||||
DAG.getNode(ISD::SRL, DL, Ptr.getValueType(),
|
||||
Ptr, DAG.getConstant(2, DL, MVT::i32)));
|
||||
Ptr = DAG.getNode(AMDGPUISD::DWORDADDR, DL, PtrVT, DWordAddr);
|
||||
|
||||
if (StoreNode->isTruncatingStore() || StoreNode->isIndexed()) {
|
||||
llvm_unreachable("Truncated and indexed stores not supported yet");
|
||||
@@ -1207,49 +1255,22 @@ SDValue R600TargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG) const {
|
||||
}
|
||||
}
|
||||
|
||||
// GLOBAL_ADDRESS has been handled above, LOCAL_ADDRESS allows all sizes
|
||||
if (AS != AMDGPUAS::PRIVATE_ADDRESS)
|
||||
return SDValue();
|
||||
|
||||
if (MemVT.bitsLT(MVT::i32))
|
||||
return lowerPrivateTruncStore(StoreNode, DAG);
|
||||
|
||||
// Lowering for indirect addressing
|
||||
const MachineFunction &MF = DAG.getMachineFunction();
|
||||
const R600FrameLowering *TFL = getSubtarget()->getFrameLowering();
|
||||
unsigned StackWidth = TFL->getStackWidth(MF);
|
||||
|
||||
Ptr = stackPtrToRegIndex(Ptr, StackWidth, DAG);
|
||||
|
||||
if (ValueVT.isVector()) {
|
||||
unsigned NumElemVT = ValueVT.getVectorNumElements();
|
||||
EVT ElemVT = ValueVT.getVectorElementType();
|
||||
SmallVector<SDValue, 4> Stores(NumElemVT);
|
||||
|
||||
assert(NumElemVT >= StackWidth && "Stack width cannot be greater than "
|
||||
"vector width in load");
|
||||
|
||||
for (unsigned i = 0; i < NumElemVT; ++i) {
|
||||
unsigned Channel, PtrIncr;
|
||||
getStackAddress(StackWidth, i, Channel, PtrIncr);
|
||||
Ptr = DAG.getNode(ISD::ADD, DL, MVT::i32, Ptr,
|
||||
DAG.getConstant(PtrIncr, DL, MVT::i32));
|
||||
SDValue Elem = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ElemVT,
|
||||
Value, DAG.getConstant(i, DL, MVT::i32));
|
||||
|
||||
Stores[i] = DAG.getNode(AMDGPUISD::REGISTER_STORE, DL, MVT::Other,
|
||||
Chain, Elem, Ptr,
|
||||
DAG.getTargetConstant(Channel, DL, MVT::i32));
|
||||
}
|
||||
Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Stores);
|
||||
} else {
|
||||
if (ValueVT == MVT::i8) {
|
||||
Value = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i32, Value);
|
||||
}
|
||||
Chain = DAG.getNode(AMDGPUISD::REGISTER_STORE, DL, MVT::Other, Chain, Value, Ptr,
|
||||
DAG.getTargetConstant(0, DL, MVT::i32)); // Channel
|
||||
// Standard i32+ store, tag it with DWORDADDR to note that the address
|
||||
// has been shifted
|
||||
if (Ptr.getOpcode() != AMDGPUISD::DWORDADDR) {
|
||||
Ptr = DAG.getNode(AMDGPUISD::DWORDADDR, DL, PtrVT, DWordAddr);
|
||||
return DAG.getStore(Chain, DL, Value, Ptr, StoreNode->getMemOperand());
|
||||
}
|
||||
|
||||
return Chain;
|
||||
// Tagged i32+ stores will be matched by patterns
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
// return (512 + (kc_bank << 12)
|
||||
@@ -1299,51 +1320,50 @@ SDValue R600TargetLowering::lowerPrivateExtLoad(SDValue Op,
|
||||
LoadSDNode *Load = cast<LoadSDNode>(Op);
|
||||
ISD::LoadExtType ExtType = Load->getExtensionType();
|
||||
EVT MemVT = Load->getMemoryVT();
|
||||
assert(Load->getAlignment() >= MemVT.getStoreSize());
|
||||
|
||||
// <SI && AS=PRIVATE && EXTLOAD && size < 32bit,
|
||||
// register (2-)byte extract.
|
||||
SDValue BasePtr = Load->getBasePtr();
|
||||
SDValue Chain = Load->getChain();
|
||||
SDValue Offset = Load->getOffset();
|
||||
|
||||
// Get Register holding the target.
|
||||
SDValue Ptr = DAG.getNode(ISD::SRL, DL, MVT::i32, Load->getBasePtr(),
|
||||
DAG.getConstant(2, DL, MVT::i32));
|
||||
// Load the Register.
|
||||
SDValue Ret = DAG.getNode(AMDGPUISD::REGISTER_LOAD, DL, Op.getValueType(),
|
||||
Load->getChain(),
|
||||
Ptr,
|
||||
DAG.getTargetConstant(0, DL, MVT::i32),
|
||||
Op.getOperand(2));
|
||||
SDValue LoadPtr = BasePtr;
|
||||
if (!Offset.isUndef()) {
|
||||
LoadPtr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr, Offset);
|
||||
}
|
||||
|
||||
// Get dword location
|
||||
// NOTE: this should be eliminated by the future SHR ptr, 2
|
||||
SDValue Ptr = DAG.getNode(ISD::AND, DL, MVT::i32, LoadPtr,
|
||||
DAG.getConstant(0xfffffffc, DL, MVT::i32));
|
||||
|
||||
// Load dword
|
||||
// TODO: can we be smarter about machine pointer info?
|
||||
SDValue Read = DAG.getLoad(MVT::i32, DL, Chain, Ptr, MachinePointerInfo());
|
||||
|
||||
// Get offset within the register.
|
||||
SDValue ByteIdx = DAG.getNode(ISD::AND, DL, MVT::i32,
|
||||
Load->getBasePtr(),
|
||||
DAG.getConstant(0x3, DL, MVT::i32));
|
||||
LoadPtr, DAG.getConstant(0x3, DL, MVT::i32));
|
||||
|
||||
// Bit offset of target byte (byteIdx * 8).
|
||||
SDValue ShiftAmt = DAG.getNode(ISD::SHL, DL, MVT::i32, ByteIdx,
|
||||
DAG.getConstant(3, DL, MVT::i32));
|
||||
|
||||
// Shift to the right.
|
||||
Ret = DAG.getNode(ISD::SRL, DL, MVT::i32, Ret, ShiftAmt);
|
||||
SDValue Ret = DAG.getNode(ISD::SRL, DL, MVT::i32, Read, ShiftAmt);
|
||||
|
||||
// Eliminate the upper bits by setting them to ...
|
||||
EVT MemEltVT = MemVT.getScalarType();
|
||||
|
||||
// ... ones.
|
||||
if (ExtType == ISD::SEXTLOAD) {
|
||||
if (ExtType == ISD::SEXTLOAD) { // ... ones.
|
||||
SDValue MemEltVTNode = DAG.getValueType(MemEltVT);
|
||||
|
||||
SDValue Ops[] = {
|
||||
DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i32, Ret, MemEltVTNode),
|
||||
Load->getChain()
|
||||
};
|
||||
|
||||
return DAG.getMergeValues(Ops, DL);
|
||||
Ret = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i32, Ret, MemEltVTNode);
|
||||
} else { // ... or zeros.
|
||||
Ret = DAG.getZeroExtendInReg(Ret, DL, MemEltVT);
|
||||
}
|
||||
|
||||
// ... or zeros.
|
||||
SDValue Ops[] = {
|
||||
DAG.getZeroExtendInReg(Ret, DL, MemEltVT),
|
||||
Load->getChain()
|
||||
Ret,
|
||||
Read.getValue(1) // This should be our output chain
|
||||
};
|
||||
|
||||
return DAG.getMergeValues(Ops, DL);
|
||||
@@ -1365,12 +1385,10 @@ SDValue R600TargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const {
|
||||
SDValue Chain = LoadNode->getChain();
|
||||
SDValue Ptr = LoadNode->getBasePtr();
|
||||
|
||||
if (LoadNode->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS && VT.isVector()) {
|
||||
SDValue MergedValues[2] = {
|
||||
scalarizeVectorLoad(LoadNode, DAG),
|
||||
Chain
|
||||
};
|
||||
return DAG.getMergeValues(MergedValues, DL);
|
||||
if ((LoadNode->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS ||
|
||||
LoadNode->getAddressSpace() == AMDGPUAS::PRIVATE_ADDRESS) &&
|
||||
VT.isVector()) {
|
||||
return scalarizeVectorLoad(LoadNode, DAG);
|
||||
}
|
||||
|
||||
int ConstantBlock = ConstantAddressBlock(LoadNode->getAddressSpace());
|
||||
@@ -1421,8 +1439,6 @@ SDValue R600TargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const {
|
||||
return DAG.getMergeValues(MergedValues, DL);
|
||||
}
|
||||
|
||||
SDValue LoweredLoad;
|
||||
|
||||
// For most operations returning SDValue() will result in the node being
|
||||
// expanded by the DAG Legalizer. This is not the case for ISD::LOAD, so we
|
||||
// need to manually expand loads that may be legal in some address spaces and
|
||||
@@ -1447,47 +1463,14 @@ SDValue R600TargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const {
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
// Lowering for indirect addressing
|
||||
const MachineFunction &MF = DAG.getMachineFunction();
|
||||
const R600FrameLowering *TFL = getSubtarget()->getFrameLowering();
|
||||
unsigned StackWidth = TFL->getStackWidth(MF);
|
||||
|
||||
Ptr = stackPtrToRegIndex(Ptr, StackWidth, DAG);
|
||||
|
||||
if (VT.isVector()) {
|
||||
unsigned NumElemVT = VT.getVectorNumElements();
|
||||
EVT ElemVT = VT.getVectorElementType();
|
||||
SDValue Loads[4];
|
||||
|
||||
assert(NumElemVT <= 4);
|
||||
assert(NumElemVT >= StackWidth && "Stack width cannot be greater than "
|
||||
"vector width in load");
|
||||
|
||||
for (unsigned i = 0; i < NumElemVT; ++i) {
|
||||
unsigned Channel, PtrIncr;
|
||||
getStackAddress(StackWidth, i, Channel, PtrIncr);
|
||||
Ptr = DAG.getNode(ISD::ADD, DL, MVT::i32, Ptr,
|
||||
DAG.getConstant(PtrIncr, DL, MVT::i32));
|
||||
Loads[i] = DAG.getNode(AMDGPUISD::REGISTER_LOAD, DL, ElemVT,
|
||||
Chain, Ptr,
|
||||
DAG.getTargetConstant(Channel, DL, MVT::i32),
|
||||
Op.getOperand(2));
|
||||
}
|
||||
EVT TargetVT = EVT::getVectorVT(*DAG.getContext(), ElemVT, NumElemVT);
|
||||
LoweredLoad = DAG.getBuildVector(TargetVT, DL, makeArrayRef(Loads, NumElemVT));
|
||||
} else {
|
||||
LoweredLoad = DAG.getNode(AMDGPUISD::REGISTER_LOAD, DL, VT,
|
||||
Chain, Ptr,
|
||||
DAG.getTargetConstant(0, DL, MVT::i32), // Channel
|
||||
Op.getOperand(2));
|
||||
// DWORDADDR ISD marks already shifted address
|
||||
if (Ptr.getOpcode() != AMDGPUISD::DWORDADDR) {
|
||||
assert(VT == MVT::i32);
|
||||
Ptr = DAG.getNode(ISD::SRL, DL, MVT::i32, Ptr, DAG.getConstant(2, DL, MVT::i32));
|
||||
Ptr = DAG.getNode(AMDGPUISD::DWORDADDR, DL, MVT::i32, Ptr);
|
||||
return DAG.getLoad(MVT::i32, DL, Chain, Ptr, LoadNode->getMemOperand());
|
||||
}
|
||||
|
||||
SDValue Ops[2] = {
|
||||
LoweredLoad,
|
||||
Chain
|
||||
};
|
||||
|
||||
return DAG.getMergeValues(Ops, DL);
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
SDValue R600TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
|
||||
|
||||
@@ -1268,6 +1268,17 @@ let Predicates = [isR600] in {
|
||||
|
||||
defm R600_ : RegisterLoadStore <R600_Reg32, FRAMEri, ADDRIndirect>;
|
||||
|
||||
// Hardcode channel to 0
|
||||
// NOTE: LSHR is not available here. LSHR is per family instruction
|
||||
def : Pat <
|
||||
(i32 (load_private ADDRIndirect:$addr) ),
|
||||
(R600_RegisterLoad FRAMEri:$addr, (i32 0))
|
||||
>;
|
||||
def : Pat <
|
||||
(store_private i32:$val, ADDRIndirect:$addr),
|
||||
(R600_RegisterStore i32:$val, FRAMEri:$addr, (i32 0))
|
||||
>;
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Pseudo instructions
|
||||
|
||||
@@ -99,6 +99,18 @@ SITargetLowering::SITargetLowering(const TargetMachine &TM,
|
||||
setOperationAction(ISD::STORE, MVT::v16i32, Custom);
|
||||
setOperationAction(ISD::STORE, MVT::i1, Custom);
|
||||
|
||||
setTruncStoreAction(MVT::v2i32, MVT::v2i16, Expand);
|
||||
setTruncStoreAction(MVT::v4i32, MVT::v4i16, Expand);
|
||||
setTruncStoreAction(MVT::v8i32, MVT::v8i16, Expand);
|
||||
setTruncStoreAction(MVT::v16i32, MVT::v16i16, Expand);
|
||||
setTruncStoreAction(MVT::v32i32, MVT::v32i16, Expand);
|
||||
setTruncStoreAction(MVT::v2i32, MVT::v2i8, Expand);
|
||||
setTruncStoreAction(MVT::v4i32, MVT::v4i8, Expand);
|
||||
setTruncStoreAction(MVT::v8i32, MVT::v8i8, Expand);
|
||||
setTruncStoreAction(MVT::v16i32, MVT::v16i8, Expand);
|
||||
setTruncStoreAction(MVT::v32i32, MVT::v32i8, Expand);
|
||||
|
||||
|
||||
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
|
||||
setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);
|
||||
setOperationAction(ISD::ConstantPool, MVT::v2i64, Expand);
|
||||
|
||||
@@ -137,8 +137,8 @@ define void @constant_sextload_v1i16_to_v1i32(<1 x i32> addrspace(1)* %out, <1 x
|
||||
|
||||
; v2i16 is naturally 4 byte aligned
|
||||
; EG: VTX_READ_32 [[DST:T[0-9]\.[XYZW]]], [[DST]], 0, #1
|
||||
; TODO: This should use DST, but for some there are redundant MOVs
|
||||
; EG: BFE_UINT {{[* ]*}}T{{[0-9].[XYZW]}}, {{PV.[XYZW]}}, literal
|
||||
; EG: BFE_UINT {{[* ]*}}T{{[0-9].[XYZW]}}, [[DST]], literal
|
||||
; EG: 16
|
||||
; EG: 16
|
||||
define void @constant_zextload_v2i16_to_v2i32(<2 x i32> addrspace(1)* %out, <2 x i16> addrspace(2)* %in) #0 {
|
||||
%load = load <2 x i16>, <2 x i16> addrspace(2)* %in
|
||||
@@ -153,11 +153,11 @@ define void @constant_zextload_v2i16_to_v2i32(<2 x i32> addrspace(1)* %out, <2 x
|
||||
; GCN-DAG: s_sext_i32_i16
|
||||
|
||||
; v2i16 is naturally 4 byte aligned
|
||||
; EG: MEM_RAT_CACHELESS STORE_RAW [[ST:T[0-9]]].XY, {{T[0-9].[XYZW]}},
|
||||
; EG: VTX_READ_32 [[DST:T[0-9]\.[XYZW]]], [[DST]], 0, #1
|
||||
; TODO: These should use DST, but for some there are redundant MOVs
|
||||
; TODO: We should also use ASHR instead of LSHR + BFE
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{PV.[XYZW]}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{PV.[XYZW]}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}[[ST]].X, [[DST]], 0.0, literal
|
||||
; TODO: We should use ASHR instead of LSHR + BFE
|
||||
; EG-DAG: BFE_INT {{[* ]*}}[[ST]].Y, {{PV\.[XYZW]}}, 0.0, literal
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
define void @constant_sextload_v2i16_to_v2i32(<2 x i32> addrspace(1)* %out, <2 x i16> addrspace(2)* %in) #0 {
|
||||
@@ -167,16 +167,23 @@ define void @constant_sextload_v2i16_to_v2i32(<2 x i32> addrspace(1)* %out, <2 x
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}constant_constant_zextload_v3i16_to_v3i32:
|
||||
; FUNC-LABEL: {{^}}constant_zextload_v3i16_to_v3i32:
|
||||
; GCN: s_load_dwordx2
|
||||
|
||||
; v3i16 is naturally 8 byte aligned
|
||||
; EG-DAG: VTX_READ_32 [[DST_HI:T[0-9]\.[XYZW]]], [[DST_HI]], 0, #1
|
||||
; EG-DAG: VTX_READ_16 [[DST_LO:T[0-9]\.[XYZW]]], [[DST_LO]], 4, #1
|
||||
; EG-DAG: MEM_RAT_CACHELESS STORE_RAW [[ST_LO:T[0-9]]].XY, {{T[0-9].[XYZW]}},
|
||||
; EG-DAG: MEM_RAT_CACHELESS STORE_RAW [[ST_HI:T[0-9]]].X, {{T[0-9].[XYZW]}},
|
||||
; EG: CF_END
|
||||
; EG-DAG: VTX_READ_32 [[DST_LO:T[0-9]\.[XYZW]]], {{T[0-9]\.[XYZW]}}, 0, #1
|
||||
; EG-DAG: VTX_READ_16 [[DST_HI:T[0-9]\.[XYZW]]], {{T[0-9]\.[XYZW]}}, 4, #1
|
||||
; TODO: This should use DST, but for some there are redundant MOVs
|
||||
; EG: LSHR {{[* ]*}}{{T[0-9].[XYZW]}}, {{T[0-9].[XYZW]}}, literal
|
||||
; EG: 16
|
||||
define void @constant_constant_zextload_v3i16_to_v3i32(<3 x i32> addrspace(1)* %out, <3 x i16> addrspace(2)* %in) {
|
||||
; EG-DAG: LSHR {{[* ]*}}[[ST_LO]].Y, {{T[0-9]\.[XYZW]}}, literal
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: AND_INT {{[* ]*}}[[ST_LO]].X, {{T[0-9]\.[XYZW]}}, literal
|
||||
; EG-DAG: AND_INT {{[* ]*}}[[ST_HI]].X, {{T[0-9]\.[XYZW]}}, literal
|
||||
; EG-DAG: 65535
|
||||
; EG-DAG: 65535
|
||||
define void @constant_zextload_v3i16_to_v3i32(<3 x i32> addrspace(1)* %out, <3 x i16> addrspace(2)* %in) {
|
||||
entry:
|
||||
%ld = load <3 x i16>, <3 x i16> addrspace(2)* %in
|
||||
%ext = zext <3 x i16> %ld to <3 x i32>
|
||||
@@ -184,19 +191,20 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}constant_constant_sextload_v3i16_to_v3i32:
|
||||
; FUNC-LABEL: {{^}}constant_sextload_v3i16_to_v3i32:
|
||||
; GCN: s_load_dwordx2
|
||||
|
||||
; EG-DAG: MEM_RAT_CACHELESS STORE_RAW [[ST_LO:T[0-9]]].XY, {{T[0-9].[XYZW]}},
|
||||
; EG-DAG: MEM_RAT_CACHELESS STORE_RAW [[ST_HI:T[0-9]]].X, {{T[0-9].[XYZW]}},
|
||||
; v3i16 is naturally 8 byte aligned
|
||||
; EG-DAG: VTX_READ_32 [[DST_HI:T[0-9]\.[XYZW]]], [[DST_HI]], 0, #1
|
||||
; EG-DAG: VTX_READ_16 [[DST_LO:T[0-9]\.[XYZW]]], [[DST_LO]], 4, #1
|
||||
; TODO: These should use DST, but for some there are redundant MOVs
|
||||
; EG-DAG: ASHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{PV.[XYZW]}}, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{T[0-9].[XYZW]}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{T[0-9].[XYZW]}}, 0.0, literal
|
||||
; EG-DAG: VTX_READ_32 [[DST_HI:T[0-9]\.[XYZW]]], [[PTR:T[0-9]\.[XYZW]]], 0, #1
|
||||
; EG-DAG: VTX_READ_16 [[DST_LO:T[0-9]\.[XYZW]]], {{T[0-9]\.[XYZW]}}, 4, #1
|
||||
; EG-DAG: ASHR {{[* ]*}}[[ST_LO]].Y, {{T[0-9]\.[XYZW]}}, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}[[ST_LO]].X, {{T[0-9]\.[XYZW]}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}[[ST_HI]].X, {{T[0-9]\.[XYZW]}}, 0.0, literal
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
define void @constant_constant_sextload_v3i16_to_v3i32(<3 x i32> addrspace(1)* %out, <3 x i16> addrspace(2)* %in) {
|
||||
define void @constant_sextload_v3i16_to_v3i32(<3 x i32> addrspace(1)* %out, <3 x i16> addrspace(2)* %in) {
|
||||
entry:
|
||||
%ld = load <3 x i16>, <3 x i16> addrspace(2)* %in
|
||||
%ext = sext <3 x i16> %ld to <3 x i32>
|
||||
@@ -204,20 +212,24 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}constant_constant_zextload_v4i16_to_v4i32:
|
||||
; FUNC-LABEL: {{^}}constant_zextload_v4i16_to_v4i32:
|
||||
; GCN: s_load_dwordx2
|
||||
; GCN-DAG: s_and_b32
|
||||
; GCN-DAG: s_lshr_b32
|
||||
|
||||
; v4i16 is naturally 8 byte aligned
|
||||
; EG: VTX_READ_64 [[DST:T[0-9]\.XY]], {{T[0-9].[XYZW]}}, 0, #1
|
||||
; TODO: These should use DST, but for some there are redundant MOVs
|
||||
; EG-DAG: BFE_UINT {{[* ]*}}T{{[0-9].[XYZW]}}, {{PV.[XYZW]}}, literal
|
||||
; EG: MEM_RAT_CACHELESS STORE_RAW [[ST:T[0-9]]].XYZW, {{T[0-9].[XYZW]}}
|
||||
; EG: VTX_READ_64 [[LD:T[0-9]]].XY, {{T[0-9].[XYZW]}}, 0, #1
|
||||
; TODO: This should use LD, but for some there are redundant MOVs
|
||||
; EG-DAG: BFE_UINT {{[* ]*}}[[ST]].Y, {{.*\.[XYZW]}}, literal
|
||||
; EG-DAG: BFE_UINT {{[* ]*}}[[ST]].W, {{.*\.[XYZW]}}, literal
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: BFE_UINT {{[* ]*}}T{{[0-9].[XYZW]}}, {{T[0-9].[XYZW]}}, literal
|
||||
; EG-DAG: AND_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{T[0-9].[XYZW]}}, literal
|
||||
; EG-DAG: 16
|
||||
define void @constant_constant_zextload_v4i16_to_v4i32(<4 x i32> addrspace(1)* %out, <4 x i16> addrspace(2)* %in) #0 {
|
||||
; EG-DAG: AND_INT {{[* ]*}}[[ST]].X, {{T[0-9]\.[XYZW]}}, literal
|
||||
; EG-DAG: AND_INT {{[* ]*}}[[ST]].Z, {{T[0-9]\.[XYZW]}}, literal
|
||||
; EG-DAG: 65535
|
||||
; EG-DAG: 65535
|
||||
define void @constant_zextload_v4i16_to_v4i32(<4 x i32> addrspace(1)* %out, <4 x i16> addrspace(2)* %in) #0 {
|
||||
%load = load <4 x i16>, <4 x i16> addrspace(2)* %in
|
||||
%ext = zext <4 x i16> %load to <4 x i32>
|
||||
store <4 x i32> %ext, <4 x i32> addrspace(1)* %out
|
||||
@@ -230,13 +242,14 @@ define void @constant_constant_zextload_v4i16_to_v4i32(<4 x i32> addrspace(1)* %
|
||||
; GCN-DAG: s_sext_i32_i16
|
||||
|
||||
; v4i16 is naturally 8 byte aligned
|
||||
; EG: VTX_READ_64 [[DST:T[0-9]\.XY]], {{T[0-9].[XYZW]}}, 0, #1
|
||||
; TODO: These should use DST, but for some there are redundant MOVs
|
||||
; EG: MEM_RAT_CACHELESS STORE_RAW [[ST:T[0-9]]].XYZW, {{T[0-9]\.[XYZW]}},
|
||||
; EG: VTX_READ_64 [[DST:T[0-9]]].XY, {{T[0-9].[XYZW]}}, 0, #1
|
||||
; TODO: This should use LD, but for some there are redundant MOVs
|
||||
; EG-DAG: BFE_INT {{[* ]*}}[[ST]].X, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}[[ST]].Z, {{.*}}, 0.0, literal
|
||||
; TODO: We should use ASHR instead of LSHR + BFE
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}[[ST]].Y, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}[[ST]].W, {{.*}}, 0.0, literal
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
@@ -254,24 +267,27 @@ define void @constant_sextload_v4i16_to_v4i32(<4 x i32> addrspace(1)* %out, <4 x
|
||||
; GCN-DAG: s_lshr_b32
|
||||
|
||||
; v8i16 is naturally 16 byte aligned
|
||||
; EG: VTX_READ_128 [[DST:T[0-9]\.XYZW]], {{T[0-9].[XYZW]}}, 0, #1
|
||||
; TODO: These should use DST, but for some there are redundant MOVs
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG: MEM_RAT_CACHELESS STORE_RAW [[ST_HI:T[0-9]]].XYZW, {{T[0-9]+.[XYZW]}},
|
||||
; EG: MEM_RAT_CACHELESS STORE_RAW [[ST_LO:T[0-9]]].XYZW, {{T[0-9]+.[XYZW]}},
|
||||
; EG: VTX_READ_128 [[DST:T[0-9]]].XYZW, {{T[0-9].[XYZW]}}, 0, #1
|
||||
; TODO: These should use LSHR instead of BFE_UINT
|
||||
; TODO: This should use DST, but for some there are redundant MOVs
|
||||
; EG-DAG: BFE_UINT {{[* ]*}}[[ST_LO]].Y, {{.*}}, literal
|
||||
; EG-DAG: BFE_UINT {{[* ]*}}[[ST_LO]].W, {{.*}}, literal
|
||||
; EG-DAG: BFE_UINT {{[* ]*}}[[ST_HI]].Y, {{.*}}, literal
|
||||
; EG-DAG: BFE_UINT {{[* ]*}}[[ST_HI]].W, {{.*}}, literal
|
||||
; EG-DAG: AND_INT {{[* ]*}}[[ST_LO]].X, {{.*}}, literal
|
||||
; EG-DAG: AND_INT {{[* ]*}}[[ST_LO]].Z, {{.*}}, literal
|
||||
; EG-DAG: AND_INT {{[* ]*}}[[ST_HI]].X, {{.*}}, literal
|
||||
; EG-DAG: AND_INT {{[* ]*}}[[ST_HI]].Z, {{.*}}, literal
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 65535
|
||||
; EG-DAG: 65535
|
||||
; EG-DAG: 65535
|
||||
; EG-DAG: 65535
|
||||
define void @constant_zextload_v8i16_to_v8i32(<8 x i32> addrspace(1)* %out, <8 x i16> addrspace(2)* %in) #0 {
|
||||
%load = load <8 x i16>, <8 x i16> addrspace(2)* %in
|
||||
%ext = zext <8 x i16> %load to <8 x i32>
|
||||
@@ -285,17 +301,19 @@ define void @constant_zextload_v8i16_to_v8i32(<8 x i32> addrspace(1)* %out, <8 x
|
||||
; GCN-DAG: s_sext_i32_i16
|
||||
|
||||
; v8i16 is naturally 16 byte aligned
|
||||
; EG: VTX_READ_128 [[DST:T[0-9]\.XYZW]], {{T[0-9].[XYZW]}}, 0, #1
|
||||
; TODO: These should use DST, but for some there are redundant MOVs
|
||||
; TODO: We should use ASHR instead of LSHR + BFE
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, 0.0, literal
|
||||
; EG: MEM_RAT_CACHELESS STORE_RAW [[ST_HI:T[0-9]]].XYZW, {{T[0-9]+.[XYZW]}},
|
||||
; EG: MEM_RAT_CACHELESS STORE_RAW [[ST_LO:T[0-9]]].XYZW, {{T[0-9]+.[XYZW]}},
|
||||
; EG: VTX_READ_128 [[DST:T[0-9]]].XYZW, {{T[0-9].[XYZW]}}, 0, #1
|
||||
; TODO: 4 of these should use ASHR instead of LSHR + BFE_INT
|
||||
; TODO: This should use DST, but for some there are redundant MOVs
|
||||
; EG-DAG: BFE_INT {{[* ]*}}[[ST_LO]].Y, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}[[ST_LO]].W, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}[[ST_HI]].Y, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}[[ST_HI]].W, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}[[ST_LO]].X, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}[[ST_LO]].Z, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}[[ST_HI]].X, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}[[ST_HI]].Z, {{.*}}, 0.0, literal
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
@@ -444,7 +462,7 @@ define void @constant_zextload_i16_to_i64(i64 addrspace(1)* %out, i16 addrspace(
|
||||
|
||||
; EG: VTX_READ_16 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
; EG: ASHR {{\**}} {{T[0-9]\.[XYZW]}}, {{.*}}, literal
|
||||
; TODO: Why not 15 ?
|
||||
; TODO: These could be expanded earlier using ASHR 15
|
||||
; EG: 31
|
||||
define void @constant_sextload_i16_to_i64(i64 addrspace(1)* %out, i16 addrspace(2)* %in) #0 {
|
||||
%a = load i16, i16 addrspace(2)* %in
|
||||
@@ -468,7 +486,7 @@ define void @constant_zextload_v1i16_to_v1i64(<1 x i64> addrspace(1)* %out, <1 x
|
||||
|
||||
; EG: VTX_READ_16 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
; EG: ASHR {{\**}} {{T[0-9]\.[XYZW]}}, {{.*}}, literal
|
||||
; TODO: Why not 15 ?
|
||||
; TODO: These could be expanded earlier using ASHR 15
|
||||
; EG: 31
|
||||
define void @constant_sextload_v1i16_to_v1i64(<1 x i64> addrspace(1)* %out, <1 x i16> addrspace(2)* %in) #0 {
|
||||
%load = load <1 x i16>, <1 x i16> addrspace(2)* %in
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,GCN-NOHSA,GCN-NOHSA-SI,FUNC %s
|
||||
; RUN: llc -mtriple=amdgcn--amdhsa -mcpu=kaveri -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,GCN-HSA,FUNC %s
|
||||
; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,GCN-NOHSA,GCN-NOHSA-VI,FUNC %s
|
||||
; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s
|
||||
; RUN: llc -march=r600 -mcpu=cayman < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s
|
||||
; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck -check-prefix=EG -check-prefix=EGCM -check-prefix=FUNC %s
|
||||
; RUN: llc -march=r600 -mcpu=cayman < %s | FileCheck -check-prefix=CM -check-prefix=EGCM -check-prefix=FUNC %s
|
||||
|
||||
; FIXME: r600 is broken because the bigger testcases spill and it's not implemented
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
; GCN-NOHSA: buffer_load_ushort v{{[0-9]+}}
|
||||
; GCN-HSA: flat_load_ushort
|
||||
|
||||
; EG: VTX_READ_16 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM: VTX_READ_16 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
define void @global_load_i16(i16 addrspace(1)* %out, i16 addrspace(1)* %in) {
|
||||
entry:
|
||||
%ld = load i16, i16 addrspace(1)* %in
|
||||
@@ -22,7 +22,7 @@ entry:
|
||||
; GCN-NOHSA: buffer_load_dword v
|
||||
; GCN-HSA: flat_load_dword v
|
||||
|
||||
; EG: VTX_READ_32 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM: VTX_READ_32 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
define void @global_load_v2i16(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %in) {
|
||||
entry:
|
||||
%ld = load <2 x i16>, <2 x i16> addrspace(1)* %in
|
||||
@@ -34,8 +34,8 @@ entry:
|
||||
; GCN-NOHSA: buffer_load_dwordx2 v
|
||||
; GCN-HSA: flat_load_dwordx2 v
|
||||
|
||||
; EG-DAG: VTX_READ_32 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
; EG-DAG: VTX_READ_16 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 4, #1
|
||||
; EGCM-DAG: VTX_READ_32 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM-DAG: VTX_READ_16 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 4, #1
|
||||
define void @global_load_v3i16(<3 x i16> addrspace(1)* %out, <3 x i16> addrspace(1)* %in) {
|
||||
entry:
|
||||
%ld = load <3 x i16>, <3 x i16> addrspace(1)* %in
|
||||
@@ -47,7 +47,7 @@ entry:
|
||||
; GCN-NOHSA: buffer_load_dwordx2
|
||||
; GCN-HSA: flat_load_dwordx2
|
||||
|
||||
; EG: VTX_READ_64 T{{[0-9]+}}.XY, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM: VTX_READ_64 T{{[0-9]+}}.XY, T{{[0-9]+}}.X, 0, #1
|
||||
define void @global_load_v4i16(<4 x i16> addrspace(1)* %out, <4 x i16> addrspace(1)* %in) {
|
||||
entry:
|
||||
%ld = load <4 x i16>, <4 x i16> addrspace(1)* %in
|
||||
@@ -59,7 +59,7 @@ entry:
|
||||
; GCN-NOHSA: buffer_load_dwordx4
|
||||
; GCN-HSA: flat_load_dwordx4
|
||||
|
||||
; EG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 0, #1
|
||||
define void @global_load_v8i16(<8 x i16> addrspace(1)* %out, <8 x i16> addrspace(1)* %in) {
|
||||
entry:
|
||||
%ld = load <8 x i16>, <8 x i16> addrspace(1)* %in
|
||||
@@ -74,8 +74,8 @@ entry:
|
||||
; GCN-HSA: flat_load_dwordx4
|
||||
; GCN-HSA: flat_load_dwordx4
|
||||
|
||||
; EG-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 0, #1
|
||||
; EG-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 16, #1
|
||||
; EGCM-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 16, #1
|
||||
define void @global_load_v16i16(<16 x i16> addrspace(1)* %out, <16 x i16> addrspace(1)* %in) {
|
||||
entry:
|
||||
%ld = load <16 x i16>, <16 x i16> addrspace(1)* %in
|
||||
@@ -90,7 +90,7 @@ entry:
|
||||
; GCN-HSA: flat_load_ushort
|
||||
; GCN-HSA: flat_store_dword
|
||||
|
||||
; EG: VTX_READ_16 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM: VTX_READ_16 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
define void @global_zextload_i16_to_i32(i32 addrspace(1)* %out, i16 addrspace(1)* %in) #0 {
|
||||
%a = load i16, i16 addrspace(1)* %in
|
||||
%ext = zext i16 %a to i32
|
||||
@@ -105,9 +105,9 @@ define void @global_zextload_i16_to_i32(i32 addrspace(1)* %out, i16 addrspace(1)
|
||||
; GCN-HSA: flat_load_sshort
|
||||
; GCN-HSA: flat_store_dword
|
||||
|
||||
; EG: VTX_READ_16 [[DST:T[0-9]\.[XYZW]]], T{{[0-9]+}}.X, 0, #1
|
||||
; EG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, [[DST]], 0.0, literal
|
||||
; EG: 16
|
||||
; EGCM: VTX_READ_16 [[DST:T[0-9]\.[XYZW]]], T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, [[DST]], 0.0, literal
|
||||
; EGCM: 16
|
||||
define void @global_sextload_i16_to_i32(i32 addrspace(1)* %out, i16 addrspace(1)* %in) #0 {
|
||||
%a = load i16, i16 addrspace(1)* %in
|
||||
%ext = sext i16 %a to i32
|
||||
@@ -119,7 +119,7 @@ define void @global_sextload_i16_to_i32(i32 addrspace(1)* %out, i16 addrspace(1)
|
||||
; GCN-NOHSA: buffer_load_ushort
|
||||
; GCN-HSA: flat_load_ushort
|
||||
|
||||
; EG: VTX_READ_16 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM: VTX_READ_16 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
define void @global_zextload_v1i16_to_v1i32(<1 x i32> addrspace(1)* %out, <1 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <1 x i16>, <1 x i16> addrspace(1)* %in
|
||||
%ext = zext <1 x i16> %load to <1 x i32>
|
||||
@@ -131,9 +131,9 @@ define void @global_zextload_v1i16_to_v1i32(<1 x i32> addrspace(1)* %out, <1 x i
|
||||
; GCN-NOHSA: buffer_load_sshort
|
||||
; GCN-HSA: flat_load_sshort
|
||||
|
||||
; EG: VTX_READ_16 [[DST:T[0-9]\.[XYZW]]], T{{[0-9]+}}.X, 0, #1
|
||||
; EG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, [[DST]], 0.0, literal
|
||||
; EG: 16
|
||||
; EGCM: VTX_READ_16 [[DST:T[0-9]\.[XYZW]]], T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, [[DST]], 0.0, literal
|
||||
; EGCM: 16
|
||||
define void @global_sextload_v1i16_to_v1i32(<1 x i32> addrspace(1)* %out, <1 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <1 x i16>, <1 x i16> addrspace(1)* %in
|
||||
%ext = sext <1 x i16> %load to <1 x i32>
|
||||
@@ -145,10 +145,9 @@ define void @global_sextload_v1i16_to_v1i32(<1 x i32> addrspace(1)* %out, <1 x i
|
||||
; GCN-NOHSA: buffer_load_dword
|
||||
; GCN-HSA: flat_load_dword
|
||||
|
||||
; EG: VTX_READ_32 [[DST:T[0-9]\.[XYZW]]], [[DST]], 0, #1
|
||||
; TODO: This should use DST, but for some there are redundant MOVs
|
||||
; EG: BFE_UINT {{[* ]*}}T{{[0-9].[XYZW]}}, {{PV.[XYZW]}}, literal
|
||||
; EG: 16
|
||||
; EGCM: VTX_READ_32 [[DST:T[0-9]\.[XYZW]]], [[DST]], 0, #1
|
||||
; EGCM: BFE_UINT {{[* ]*}}T{{[0-9].[XYZW]}}, [[DST]], literal
|
||||
; EGCM: 16
|
||||
define void @global_zextload_v2i16_to_v2i32(<2 x i32> addrspace(1)* %out, <2 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <2 x i16>, <2 x i16> addrspace(1)* %in
|
||||
%ext = zext <2 x i16> %load to <2 x i32>
|
||||
@@ -161,13 +160,14 @@ define void @global_zextload_v2i16_to_v2i32(<2 x i32> addrspace(1)* %out, <2 x i
|
||||
|
||||
; GCN-HSA: flat_load_dword
|
||||
|
||||
; EG: VTX_READ_32 [[DST:T[0-9]\.[XYZW]]], [[DST]], 0, #1
|
||||
; TODO: These should use DST, but for some there are redundant MOVs
|
||||
; TODO: We should also use ASHR instead of LSHR + BFE
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{PV.[XYZW]}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{PV.[XYZW]}}, 0.0, literal
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG: MEM_RAT_CACHELESS STORE_RAW [[ST:T[0-9]]].XY, {{T[0-9]\.[XYZW]}},
|
||||
; CM: MEM_RAT_CACHELESS STORE_DWORD [[ST:T[0-9]]], {{T[0-9]\.[XYZW]}}
|
||||
; EGCM: VTX_READ_32 [[DST:T[0-9].[XYZW]]], [[DST]], 0, #1
|
||||
; TODO: This should use ASHR instead of LSHR + BFE
|
||||
; EGCM-DAG: BFE_INT {{[* ]*}}[[ST]].X, [[DST]], 0.0, literal
|
||||
; EGCM-DAG: BFE_INT {{[* ]*}}[[ST]].Y, {{PV.[XYZW]}}, 0.0, literal
|
||||
; EGCM-DAG: 16
|
||||
; EGCM-DAG: 16
|
||||
define void @global_sextload_v2i16_to_v2i32(<2 x i32> addrspace(1)* %out, <2 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <2 x i16>, <2 x i16> addrspace(1)* %in
|
||||
%ext = sext <2 x i16> %load to <2 x i32>
|
||||
@@ -175,16 +175,22 @@ define void @global_sextload_v2i16_to_v2i32(<2 x i32> addrspace(1)* %out, <2 x i
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}global_global_zextload_v3i16_to_v3i32:
|
||||
; FUNC-LABEL: {{^}}global_zextload_v3i16_to_v3i32:
|
||||
; GCN-NOHSA: buffer_load_dwordx2
|
||||
; GCN-HSA: flat_load_dwordx2
|
||||
|
||||
; EG-DAG: VTX_READ_32 [[DST_HI:T[0-9]\.[XYZW]]], [[DST_HI]], 0, #1
|
||||
; EG-DAG: VTX_READ_16 [[DST_LO:T[0-9]\.[XYZW]]], [[DST_LO]], 4, #1
|
||||
; CM: MEM_RAT_CACHELESS STORE_DWORD [[ST_HI:T[0-9]]].X, {{T[0-9]\.[XYZW]}}
|
||||
; CM: MEM_RAT_CACHELESS STORE_DWORD [[ST_LO:T[0-9]]], {{T[0-9]\.[XYZW]}}
|
||||
; EG: MEM_RAT_CACHELESS STORE_RAW [[ST_HI:T[0-9]]].X, {{T[0-9]\.[XYZW]}},
|
||||
; EG: MEM_RAT_CACHELESS STORE_RAW [[ST_LO:T[0-9]]].XY, {{T[0-9]\.[XYZW]}},
|
||||
; EGCM-DAG: VTX_READ_32 [[DST_LO:T[0-9]\.[XYZW]]], {{T[0-9]\.[XYZW]}}, 0, #1
|
||||
; EGCM-DAG: VTX_READ_16 [[DST_HI:T[0-9]\.[XYZW]]], {{T[0-9]\.[XYZW]}}, 4, #1
|
||||
; TODO: This should use DST, but for some there are redundant MOVs
|
||||
; EG: LSHR {{[* ]*}}{{T[0-9].[XYZW]}}, {{T[0-9].[XYZW]}}, literal
|
||||
; EG: 16
|
||||
define void @global_global_zextload_v3i16_to_v3i32(<3 x i32> addrspace(1)* %out, <3 x i16> addrspace(1)* %in) {
|
||||
; EGCM: LSHR {{[* ]*}}[[ST_LO]].Y, {{T[0-9]\.[XYZW]}}, literal
|
||||
; EGCM: 16
|
||||
; EGCM: AND_INT {{[* ]*}}[[ST_LO]].X, {{T[0-9]\.[XYZW]}}, literal
|
||||
; EGCM: AND_INT {{[* ]*}}[[ST_HI]].X, [[DST_HI]], literal
|
||||
define void @global_zextload_v3i16_to_v3i32(<3 x i32> addrspace(1)* %out, <3 x i16> addrspace(1)* %in) {
|
||||
entry:
|
||||
%ld = load <3 x i16>, <3 x i16> addrspace(1)* %in
|
||||
%ext = zext <3 x i16> %ld to <3 x i32>
|
||||
@@ -192,19 +198,23 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}global_global_sextload_v3i16_to_v3i32:
|
||||
; FUNC-LABEL: {{^}}global_sextload_v3i16_to_v3i32:
|
||||
; GCN-NOHSA: buffer_load_dwordx2
|
||||
; GCN-HSA: flat_load_dwordx2
|
||||
|
||||
; EG-DAG: VTX_READ_32 [[DST_HI:T[0-9]\.[XYZW]]], [[DST_HI]], 0, #1
|
||||
; EG-DAG: VTX_READ_16 [[DST_LO:T[0-9]\.[XYZW]]], [[DST_LO]], 4, #1
|
||||
; TODO: These should use DST, but for some there are redundant MOVs
|
||||
; EG-DAG: ASHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{PV.[XYZW]}}, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{T[0-9].[XYZW]}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{T[0-9].[XYZW]}}, 0.0, literal
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
define void @global_global_sextload_v3i16_to_v3i32(<3 x i32> addrspace(1)* %out, <3 x i16> addrspace(1)* %in) {
|
||||
; CM: MEM_RAT_CACHELESS STORE_DWORD [[ST_HI:T[0-9]]].X, {{T[0-9]\.[XYZW]}}
|
||||
; CM: MEM_RAT_CACHELESS STORE_DWORD [[ST_LO:T[0-9]]], {{T[0-9]\.[XYZW]}}
|
||||
; EG: MEM_RAT_CACHELESS STORE_RAW [[ST_HI:T[0-9]]].X, {{T[0-9]\.[XYZW]}},
|
||||
; EG: MEM_RAT_CACHELESS STORE_RAW [[ST_LO:T[0-9]]].XY, {{T[0-9]\.[XYZW]}},
|
||||
; EGCM-DAG: VTX_READ_32 [[DST_LO:T[0-9]\.[XYZW]]], {{T[0-9].[XYZW]}}, 0, #1
|
||||
; EGCM-DAG: VTX_READ_16 [[DST_HI:T[0-9]\.[XYZW]]], {{T[0-9].[XYZW]}}, 4, #1
|
||||
; TODO: This should use DST, but for some there are redundant MOVs
|
||||
; EGCM-DAG: ASHR {{[* ]*}}[[ST_LO]].Y, {{T[0-9]\.[XYZW]}}, literal
|
||||
; EGCM-DAG: BFE_INT {{[* ]*}}[[ST_LO]].X, {{T[0-9]\.[XYZW]}}, 0.0, literal
|
||||
; EGCM-DAG: BFE_INT {{[* ]*}}[[ST_HI]].X, [[DST_HI]], 0.0, literal
|
||||
; EGCM-DAG: 16
|
||||
; EGCM-DAG: 16
|
||||
define void @global_sextload_v3i16_to_v3i32(<3 x i32> addrspace(1)* %out, <3 x i16> addrspace(1)* %in) {
|
||||
entry:
|
||||
%ld = load <3 x i16>, <3 x i16> addrspace(1)* %in
|
||||
%ext = sext <3 x i16> %ld to <3 x i32>
|
||||
@@ -212,19 +222,22 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}global_global_zextload_v4i16_to_v4i32:
|
||||
; FUNC-LABEL: {{^}}global_zextload_v4i16_to_v4i32:
|
||||
; GCN-NOHSA: buffer_load_dwordx2
|
||||
|
||||
; GCN-HSA: flat_load_dwordx2
|
||||
|
||||
; EG: VTX_READ_64 [[DST:T[0-9]\.XY]], {{T[0-9].[XYZW]}}, 0, #1
|
||||
; TODO: These should use DST, but for some there are redundant MOVs
|
||||
; EG-DAG: BFE_UINT {{[* ]*}}T{{[0-9].[XYZW]}}, {{T[0-9].[XYZW]}}, literal
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: BFE_UINT {{[* ]*}}T{{[0-9].[XYZW]}}, {{T[0-9].[XYZW]}}, literal
|
||||
; EG-DAG: AND_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{T[0-9].[XYZW]}}, literal
|
||||
; EG-DAG: 16
|
||||
define void @global_global_zextload_v4i16_to_v4i32(<4 x i32> addrspace(1)* %out, <4 x i16> addrspace(1)* %in) #0 {
|
||||
; CM: MEM_RAT_CACHELESS STORE_DWORD [[ST:T[0-9]]], {{T[0-9]\.[XYZW]}}
|
||||
; EG: MEM_RAT_CACHELESS STORE_RAW [[ST:T[0-9]]].XYZW, {{T[0-9]\.[XYZW]}},
|
||||
; EGCM: VTX_READ_64 [[DST:T[0-9]]].XY, {{T[0-9].[XYZW]}}, 0, #1
|
||||
; TODO: This should use DST, but for some there are redundant MOVs
|
||||
; EGCM-DAG: BFE_UINT {{[* ]*}}[[ST]].Y, {{.*}}, literal
|
||||
; EGCM-DAG: 16
|
||||
; EGCM-DAG: BFE_UINT {{[* ]*}}[[ST]].W, {{.*}}, literal
|
||||
; EGCM-DAG: AND_INT {{[* ]*}}[[ST]].X, {{.*}}, literal
|
||||
; EGCM-DAG: AND_INT {{[* ]*}}[[ST]].Z, {{.*}}, literal
|
||||
; EGCM-DAG: 16
|
||||
define void @global_zextload_v4i16_to_v4i32(<4 x i32> addrspace(1)* %out, <4 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <4 x i16>, <4 x i16> addrspace(1)* %in
|
||||
%ext = zext <4 x i16> %load to <4 x i32>
|
||||
store <4 x i32> %ext, <4 x i32> addrspace(1)* %out
|
||||
@@ -236,17 +249,19 @@ define void @global_global_zextload_v4i16_to_v4i32(<4 x i32> addrspace(1)* %out,
|
||||
|
||||
; GCN-HSA: flat_load_dwordx2
|
||||
|
||||
; EG: VTX_READ_64 [[DST:T[0-9]\.XY]], {{T[0-9].[XYZW]}}, 0, #1
|
||||
; TODO: These should use DST, but for some there are redundant MOVs
|
||||
; CM: MEM_RAT_CACHELESS STORE_DWORD [[ST:T[0-9]]], {{T[0-9]\.[XYZW]}}
|
||||
; EG: MEM_RAT_CACHELESS STORE_RAW [[ST:T[0-9]]].XYZW, {{T[0-9]\.[XYZW]}},
|
||||
; EGCM: VTX_READ_64 [[DST:T[0-9]]].XY, {{T[0-9].[XYZW]}}, 0, #1
|
||||
; TODO: We should use ASHR instead of LSHR + BFE
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, 0.0, literal
|
||||
; EG-DAG: BFE_INT {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, 0.0, literal
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; TODO: This should use DST, but for some there are redundant MOVs
|
||||
; EGCM-DAG: BFE_INT {{[* ]*}}[[ST]].X, {{.*}}, 0.0, literal
|
||||
; EGCM-DAG: BFE_INT {{[* ]*}}[[ST]].Y, {{.*}}, 0.0, literal
|
||||
; EGCM-DAG: BFE_INT {{[* ]*}}[[ST]].Z, {{.*}}, 0.0, literal
|
||||
; EGCM-DAG: BFE_INT {{[* ]*}}[[ST]].W, {{.*}}, 0.0, literal
|
||||
; EGCM-DAG: 16
|
||||
; EGCM-DAG: 16
|
||||
; EGCM-DAG: 16
|
||||
; EGCM-DAG: 16
|
||||
define void @global_sextload_v4i16_to_v4i32(<4 x i32> addrspace(1)* %out, <4 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <4 x i16>, <4 x i16> addrspace(1)* %in
|
||||
%ext = sext <4 x i16> %load to <4 x i32>
|
||||
@@ -258,16 +273,29 @@ define void @global_sextload_v4i16_to_v4i32(<4 x i32> addrspace(1)* %out, <4 x i
|
||||
; GCN-NOHSA: buffer_load_dwordx4
|
||||
; GCN-HSA: flat_load_dwordx4
|
||||
|
||||
; EG: VTX_READ_128 [[DST:T[0-9]\.XYZW]], {{T[0-9].[XYZW]}}, 0, #1
|
||||
; TODO: These should use DST, but for some there are redundant MOVs
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; CM-DAG: MEM_RAT_CACHELESS STORE_DWORD [[ST_LO:T[0-9]]], {{T[0-9]\.[XYZW]}}
|
||||
; CM-DAG: MEM_RAT_CACHELESS STORE_DWORD [[ST_HI:T[0-9]]], {{T[0-9]\.[XYZW]}}
|
||||
; EG-DAG: MEM_RAT_CACHELESS STORE_RAW [[ST_LO:T[0-9]]].XYZW, {{T[0-9]\.[XYZW]}},
|
||||
; EG-DAG: MEM_RAT_CACHELESS STORE_RAW [[ST_HI:T[0-9]]].XYZW, {{T[0-9]\.[XYZW]}},
|
||||
; EGCM: CF_END
|
||||
; EGCM: VTX_READ_128 [[DST:T[0-9]]].XYZW, {{T[0-9].[XYZW]}}, 0, #1
|
||||
; TODO: These should use LSHR instead of BFE_UINT
|
||||
; EGCM-DAG: BFE_UINT {{[* ]*}}[[ST_LO]].Y, {{.*}}, literal
|
||||
; EGCM-DAG: BFE_UINT {{[* ]*}}[[ST_LO]].W, {{.*}}, literal
|
||||
; EGCM-DAG: BFE_UINT {{[* ]*}}[[ST_HI]].Y, {{.*}}, literal
|
||||
; EGCM-DAG: BFE_UINT {{[* ]*}}[[ST_HI]].W, {{.*}}, literal
|
||||
; EGCM-DAG: AND_INT {{[* ]*}}[[ST_LO]].X, {{.*}}, literal
|
||||
; EGCM-DAG: AND_INT {{[* ]*}}[[ST_LO]].Z, {{.*}}, literal
|
||||
; EGCM-DAG: AND_INT {{[* ]*}}[[ST_HI]].X, {{.*}}, literal
|
||||
; EGCM-DAG: AND_INT {{[* ]*}}[[ST_HI]].Z, {{.*}}, literal
|
||||
; EGCM-DAG: 65535
|
||||
; EGCM-DAG: 65535
|
||||
; EGCM-DAG: 65535
|
||||
; EGCM-DAG: 65535
|
||||
; EGCM-DAG: 16
|
||||
; EGCM-DAG: 16
|
||||
; EGCM-DAG: 16
|
||||
; EGCM-DAG: 16
|
||||
define void @global_zextload_v8i16_to_v8i32(<8 x i32> addrspace(1)* %out, <8 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <8 x i16>, <8 x i16> addrspace(1)* %in
|
||||
%ext = zext <8 x i16> %load to <8 x i32>
|
||||
@@ -279,24 +307,29 @@ define void @global_zextload_v8i16_to_v8i32(<8 x i32> addrspace(1)* %out, <8 x i
|
||||
; GCN-NOHSA: buffer_load_dwordx4
|
||||
; GCN-HSA: flat_load_dwordx4
|
||||
|
||||
; EG: VTX_READ_128 [[DST:T[0-9]\.XYZW]], {{T[0-9].[XYZW]}}, 0, #1
|
||||
; TODO: These should use DST, but for some there are redundant MOVs
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: LSHR {{[* ]*}}T{{[0-9].[XYZW]}}, {{.*}}, literal
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; EG-DAG: 16
|
||||
; CM-DAG: MEM_RAT_CACHELESS STORE_DWORD [[ST_LO:T[0-9]]], {{T[0-9]\.[XYZW]}}
|
||||
; CM-DAG: MEM_RAT_CACHELESS STORE_DWORD [[ST_HI:T[0-9]]], {{T[0-9]\.[XYZW]}}
|
||||
; EG-DAG: MEM_RAT_CACHELESS STORE_RAW [[ST_LO:T[0-9]]].XYZW, {{T[0-9]\.[XYZW]}},
|
||||
; EG-DAG: MEM_RAT_CACHELESS STORE_RAW [[ST_HI:T[0-9]]].XYZW, {{T[0-9]\.[XYZW]}},
|
||||
; EGCM: CF_END
|
||||
; EGCM: VTX_READ_128 [[DST:T[0-9]]].XYZW, {{T[0-9].[XYZW]}}, 0, #1
|
||||
; TODO: These should use ASHR instead of LSHR + BFE_INT
|
||||
; EGCM-DAG: BFE_INT {{[* ]*}}[[ST_LO]].Y, {{.*}}, 0.0, literal
|
||||
; EGCM-DAG: BFE_INT {{[* ]*}}[[ST_LO]].W, {{.*}}, 0.0, literal
|
||||
; EGCM-DAG: BFE_INT {{[* ]*}}[[ST_HI]].Y, {{.*}}, 0.0, literal
|
||||
; EGCM-DAG: BFE_INT {{[* ]*}}[[ST_HI]].W, {{.*}}, 0.0, literal
|
||||
; EGCM-DAG: BFE_INT {{[* ]*}}[[ST_LO]].X, {{.*}}, 0.0, literal
|
||||
; EGCM-DAG: BFE_INT {{[* ]*}}[[ST_LO]].Z, {{.*}}, 0.0, literal
|
||||
; EGCM-DAG: BFE_INT {{[* ]*}}[[ST_HI]].X, {{.*}}, 0.0, literal
|
||||
; EGCM-DAG: BFE_INT {{[* ]*}}[[ST_HI]].Z, {{.*}}, 0.0, literal
|
||||
; EGCM-DAG: 16
|
||||
; EGCM-DAG: 16
|
||||
; EGCM-DAG: 16
|
||||
; EGCM-DAG: 16
|
||||
; EGCM-DAG: 16
|
||||
; EGCM-DAG: 16
|
||||
; EGCM-DAG: 16
|
||||
; EGCM-DAG: 16
|
||||
define void @global_sextload_v8i16_to_v8i32(<8 x i32> addrspace(1)* %out, <8 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <8 x i16>, <8 x i16> addrspace(1)* %in
|
||||
%ext = sext <8 x i16> %load to <8 x i32>
|
||||
@@ -311,8 +344,8 @@ define void @global_sextload_v8i16_to_v8i32(<8 x i32> addrspace(1)* %out, <8 x i
|
||||
; GCN-HSA: flat_load_dwordx4
|
||||
; GCN-HSA: flat_load_dwordx4
|
||||
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 0, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 16, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 0, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 16, #1
|
||||
define void @global_zextload_v16i16_to_v16i32(<16 x i32> addrspace(1)* %out, <16 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <16 x i16>, <16 x i16> addrspace(1)* %in
|
||||
%ext = zext <16 x i16> %load to <16 x i32>
|
||||
@@ -322,8 +355,8 @@ define void @global_zextload_v16i16_to_v16i32(<16 x i32> addrspace(1)* %out, <16
|
||||
|
||||
; FUNC-LABEL: {{^}}global_sextload_v16i16_to_v16i32:
|
||||
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 0, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 16, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 0, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 16, #1
|
||||
define void @global_sextload_v16i16_to_v16i32(<16 x i32> addrspace(1)* %out, <16 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <16 x i16>, <16 x i16> addrspace(1)* %in
|
||||
%ext = sext <16 x i16> %load to <16 x i32>
|
||||
@@ -342,10 +375,10 @@ define void @global_sextload_v16i16_to_v16i32(<16 x i32> addrspace(1)* %out, <16
|
||||
; GCN-HSA: flat_load_dwordx4
|
||||
; GCN-HSA: flat_load_dwordx4
|
||||
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 0, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 16, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 32, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 48, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 0, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 16, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 32, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 48, #1
|
||||
define void @global_zextload_v32i16_to_v32i32(<32 x i32> addrspace(1)* %out, <32 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <32 x i16>, <32 x i16> addrspace(1)* %in
|
||||
%ext = zext <32 x i16> %load to <32 x i32>
|
||||
@@ -364,10 +397,10 @@ define void @global_zextload_v32i16_to_v32i32(<32 x i32> addrspace(1)* %out, <32
|
||||
; GCN-HSA: flat_load_dwordx4
|
||||
; GCN-HSA: flat_load_dwordx4
|
||||
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 0, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 16, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 32, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 48, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 0, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 16, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 32, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 48, #1
|
||||
define void @global_sextload_v32i16_to_v32i32(<32 x i32> addrspace(1)* %out, <32 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <32 x i16>, <32 x i16> addrspace(1)* %in
|
||||
%ext = sext <32 x i16> %load to <32 x i32>
|
||||
@@ -394,14 +427,14 @@ define void @global_sextload_v32i16_to_v32i32(<32 x i32> addrspace(1)* %out, <32
|
||||
; GCN-HSA: flat_load_dwordx4
|
||||
; GCN-HSA: flat_load_dwordx4
|
||||
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 0, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 16, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 32, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 48, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 64, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 80, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 96, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 112, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 0, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 16, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 32, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 48, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 64, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 80, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 96, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 112, #1
|
||||
define void @global_zextload_v64i16_to_v64i32(<64 x i32> addrspace(1)* %out, <64 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <64 x i16>, <64 x i16> addrspace(1)* %in
|
||||
%ext = zext <64 x i16> %load to <64 x i32>
|
||||
@@ -411,14 +444,14 @@ define void @global_zextload_v64i16_to_v64i32(<64 x i32> addrspace(1)* %out, <64
|
||||
|
||||
; FUNC-LABEL: {{^}}global_sextload_v64i16_to_v64i32:
|
||||
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 0, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 16, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 32, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 48, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 64, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 80, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 96, #1
|
||||
; EG-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 112, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 0, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 16, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 32, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 48, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 64, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 80, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 96, #1
|
||||
; EGCM-DAG: VTX_READ_128 {{T[0-9]+\.XYZW}}, {{T[0-9]+.[XYZW]}}, 112, #1
|
||||
define void @global_sextload_v64i16_to_v64i32(<64 x i32> addrspace(1)* %out, <64 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <64 x i16>, <64 x i16> addrspace(1)* %in
|
||||
%ext = sext <64 x i16> %load to <64 x i32>
|
||||
@@ -434,8 +467,8 @@ define void @global_sextload_v64i16_to_v64i32(<64 x i32> addrspace(1)* %out, <64
|
||||
; GCN-NOHSA: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]]
|
||||
; GCN-HSA: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[}}[[LO]]:[[HI]]{{\]}}
|
||||
|
||||
; EG: VTX_READ_16 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
; EG: MOV {{.*}}, 0.0
|
||||
; EGCM: VTX_READ_16 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM: MOV {{.*}}, 0.0
|
||||
define void @global_zextload_i16_to_i64(i64 addrspace(1)* %out, i16 addrspace(1)* %in) #0 {
|
||||
%a = load i16, i16 addrspace(1)* %in
|
||||
%ext = zext i16 %a to i64
|
||||
@@ -458,10 +491,10 @@ define void @global_zextload_i16_to_i64(i64 addrspace(1)* %out, i16 addrspace(1)
|
||||
; GCN-NOHSA: buffer_store_dwordx2 v{{\[}}[[LO]]:[[HI]]]
|
||||
; GCN-HSA: flat_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[}}[[LO]]:[[HI]]{{\]}}
|
||||
|
||||
; EG: VTX_READ_16 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
; EG: ASHR {{\**}} {{T[0-9]\.[XYZW]}}, {{.*}}, literal
|
||||
; TODO: Why not 15 ?
|
||||
; EG: 31
|
||||
; EGCM: VTX_READ_16 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM: ASHR {{\**}} {{T[0-9]\.[XYZW]}}, {{.*}}, literal
|
||||
; TODO: These could be expanded earlier using ASHR 15
|
||||
; EGCM: 31
|
||||
define void @global_sextload_i16_to_i64(i64 addrspace(1)* %out, i16 addrspace(1)* %in) #0 {
|
||||
%a = load i16, i16 addrspace(1)* %in
|
||||
%ext = sext i16 %a to i64
|
||||
@@ -471,8 +504,8 @@ define void @global_sextload_i16_to_i64(i64 addrspace(1)* %out, i16 addrspace(1)
|
||||
|
||||
; FUNC-LABEL: {{^}}global_zextload_v1i16_to_v1i64:
|
||||
|
||||
; EG: VTX_READ_16 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
; EG: MOV {{.*}}, 0.0
|
||||
; EGCM: VTX_READ_16 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM: MOV {{.*}}, 0.0
|
||||
define void @global_zextload_v1i16_to_v1i64(<1 x i64> addrspace(1)* %out, <1 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <1 x i16>, <1 x i16> addrspace(1)* %in
|
||||
%ext = zext <1 x i16> %load to <1 x i64>
|
||||
@@ -482,10 +515,10 @@ define void @global_zextload_v1i16_to_v1i64(<1 x i64> addrspace(1)* %out, <1 x i
|
||||
|
||||
; FUNC-LABEL: {{^}}global_sextload_v1i16_to_v1i64:
|
||||
|
||||
; EG: VTX_READ_16 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
; EG: ASHR {{\**}} {{T[0-9]\.[XYZW]}}, {{.*}}, literal
|
||||
; TODO: Why not 15 ?
|
||||
; EG: 31
|
||||
; EGCM: VTX_READ_16 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM: ASHR {{\**}} {{T[0-9]\.[XYZW]}}, {{.*}}, literal
|
||||
; TODO: These could be expanded earlier using ASHR 15
|
||||
; EGCM: 31
|
||||
define void @global_sextload_v1i16_to_v1i64(<1 x i64> addrspace(1)* %out, <1 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <1 x i16>, <1 x i16> addrspace(1)* %in
|
||||
%ext = sext <1 x i16> %load to <1 x i64>
|
||||
@@ -503,7 +536,7 @@ define void @global_zextload_v2i16_to_v2i64(<2 x i64> addrspace(1)* %out, <2 x i
|
||||
|
||||
; FUNC-LABEL: {{^}}global_sextload_v2i16_to_v2i64:
|
||||
|
||||
; EG: VTX_READ_32 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM: VTX_READ_32 T{{[0-9]+}}.X, T{{[0-9]+}}.X, 0, #1
|
||||
define void @global_sextload_v2i16_to_v2i64(<2 x i64> addrspace(1)* %out, <2 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <2 x i16>, <2 x i16> addrspace(1)* %in
|
||||
%ext = sext <2 x i16> %load to <2 x i64>
|
||||
@@ -513,7 +546,7 @@ define void @global_sextload_v2i16_to_v2i64(<2 x i64> addrspace(1)* %out, <2 x i
|
||||
|
||||
; FUNC-LABEL: {{^}}global_zextload_v4i16_to_v4i64:
|
||||
|
||||
; EG: VTX_READ_64 T{{[0-9]+}}.XY, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM: VTX_READ_64 T{{[0-9]+}}.XY, T{{[0-9]+}}.X, 0, #1
|
||||
define void @global_zextload_v4i16_to_v4i64(<4 x i64> addrspace(1)* %out, <4 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <4 x i16>, <4 x i16> addrspace(1)* %in
|
||||
%ext = zext <4 x i16> %load to <4 x i64>
|
||||
@@ -523,7 +556,7 @@ define void @global_zextload_v4i16_to_v4i64(<4 x i64> addrspace(1)* %out, <4 x i
|
||||
|
||||
; FUNC-LABEL: {{^}}global_sextload_v4i16_to_v4i64:
|
||||
|
||||
; EG: VTX_READ_64 T{{[0-9]+}}.XY, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM: VTX_READ_64 T{{[0-9]+}}.XY, T{{[0-9]+}}.X, 0, #1
|
||||
define void @global_sextload_v4i16_to_v4i64(<4 x i64> addrspace(1)* %out, <4 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <4 x i16>, <4 x i16> addrspace(1)* %in
|
||||
%ext = sext <4 x i16> %load to <4 x i64>
|
||||
@@ -533,7 +566,7 @@ define void @global_sextload_v4i16_to_v4i64(<4 x i64> addrspace(1)* %out, <4 x i
|
||||
|
||||
; FUNC-LABEL: {{^}}global_zextload_v8i16_to_v8i64:
|
||||
|
||||
; EG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 0, #1
|
||||
define void @global_zextload_v8i16_to_v8i64(<8 x i64> addrspace(1)* %out, <8 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <8 x i16>, <8 x i16> addrspace(1)* %in
|
||||
%ext = zext <8 x i16> %load to <8 x i64>
|
||||
@@ -543,7 +576,7 @@ define void @global_zextload_v8i16_to_v8i64(<8 x i64> addrspace(1)* %out, <8 x i
|
||||
|
||||
; FUNC-LABEL: {{^}}global_sextload_v8i16_to_v8i64:
|
||||
|
||||
; EG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 0, #1
|
||||
define void @global_sextload_v8i16_to_v8i64(<8 x i64> addrspace(1)* %out, <8 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <8 x i16>, <8 x i16> addrspace(1)* %in
|
||||
%ext = sext <8 x i16> %load to <8 x i64>
|
||||
@@ -553,8 +586,8 @@ define void @global_sextload_v8i16_to_v8i64(<8 x i64> addrspace(1)* %out, <8 x i
|
||||
|
||||
; FUNC-LABEL: {{^}}global_zextload_v16i16_to_v16i64:
|
||||
|
||||
; EG-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 0, #1
|
||||
; EG-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 16, #1
|
||||
; EGCM-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 16, #1
|
||||
define void @global_zextload_v16i16_to_v16i64(<16 x i64> addrspace(1)* %out, <16 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <16 x i16>, <16 x i16> addrspace(1)* %in
|
||||
%ext = zext <16 x i16> %load to <16 x i64>
|
||||
@@ -564,8 +597,8 @@ define void @global_zextload_v16i16_to_v16i64(<16 x i64> addrspace(1)* %out, <16
|
||||
|
||||
; FUNC-LABEL: {{^}}global_sextload_v16i16_to_v16i64:
|
||||
|
||||
; EG-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 0, #1
|
||||
; EG-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 16, #1
|
||||
; EGCM-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 16, #1
|
||||
define void @global_sextload_v16i16_to_v16i64(<16 x i64> addrspace(1)* %out, <16 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <16 x i16>, <16 x i16> addrspace(1)* %in
|
||||
%ext = sext <16 x i16> %load to <16 x i64>
|
||||
@@ -575,10 +608,10 @@ define void @global_sextload_v16i16_to_v16i64(<16 x i64> addrspace(1)* %out, <16
|
||||
|
||||
; FUNC-LABEL: {{^}}global_zextload_v32i16_to_v32i64:
|
||||
|
||||
; EG-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 0, #1
|
||||
; EG-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 16, #1
|
||||
; EG-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 32, #1
|
||||
; EG-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 48, #1
|
||||
; EGCM-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 16, #1
|
||||
; EGCM-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 32, #1
|
||||
; EGCM-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 48, #1
|
||||
define void @global_zextload_v32i16_to_v32i64(<32 x i64> addrspace(1)* %out, <32 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <32 x i16>, <32 x i16> addrspace(1)* %in
|
||||
%ext = zext <32 x i16> %load to <32 x i64>
|
||||
@@ -588,10 +621,10 @@ define void @global_zextload_v32i16_to_v32i64(<32 x i64> addrspace(1)* %out, <32
|
||||
|
||||
; FUNC-LABEL: {{^}}global_sextload_v32i16_to_v32i64:
|
||||
|
||||
; EG-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 0, #1
|
||||
; EG-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 16, #1
|
||||
; EG-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 32, #1
|
||||
; EG-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 48, #1
|
||||
; EGCM-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 0, #1
|
||||
; EGCM-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 16, #1
|
||||
; EGCM-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 32, #1
|
||||
; EGCM-DAG: VTX_READ_128 T{{[0-9]+}}.XYZW, T{{[0-9]+}}.X, 48, #1
|
||||
define void @global_sextload_v32i16_to_v32i64(<32 x i64> addrspace(1)* %out, <32 x i16> addrspace(1)* %in) #0 {
|
||||
%load = load <32 x i16>, <32 x i16> addrspace(1)* %in
|
||||
%ext = sext <32 x i16> %load to <32 x i64>
|
||||
|
||||
@@ -0,0 +1,743 @@
|
||||
; RUN: llc -march=amdgcn -mcpu=verde -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
|
||||
; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
|
||||
; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s
|
||||
; RUN: llc -march=r600 -mcpu=cayman < %s | FileCheck -check-prefix=CM -check-prefix=FUNC %s
|
||||
|
||||
; FUNC-LABEL: {{^}}store_i1:
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; SI: buffer_store_byte
|
||||
define void @store_i1(i1 addrspace(0)* %out) {
|
||||
entry:
|
||||
store i1 true, i1 addrspace(0)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; i8 store
|
||||
; FUNC-LABEL: {{^}}store_i8:
|
||||
; EG: LSHR * [[ADDRESS:T[0-9]\.[XYZW]]], KC0[2].Y, literal.x
|
||||
; EG-NEXT: 2
|
||||
; EG: MOVA_INT * AR.x (MASKED)
|
||||
; EG: MOV [[OLD:T[0-9]\.[XYZW]]], {{.*}}AR.x
|
||||
|
||||
; IG 0: Get the byte index and truncate the value
|
||||
; EG: AND_INT * T{{[0-9]}}.[[BI_CHAN:[XYZW]]], KC0[2].Y, literal.x
|
||||
; EG: LSHL * T{{[0-9]}}.[[SHIFT_CHAN:[XYZW]]], PV.[[BI_CHAN]], literal.x
|
||||
; EG-NEXT: 3(4.203895e-45)
|
||||
; EG: AND_INT * T{{[0-9]}}.[[TRUNC_CHAN:[XYZW]]], KC0[2].Z, literal.x
|
||||
; EG-NEXT: 255(3.573311e-43)
|
||||
|
||||
; EG: NOT_INT
|
||||
; EG: AND_INT {{[\* ]*}}[[CLR_CHAN:T[0-9]\.[XYZW]]], {{.*}}[[OLD]]
|
||||
; EG: OR_INT * [[RES:T[0-9]\.[XYZW]]]
|
||||
; TODO: Is the reload necessary?
|
||||
; EG: MOVA_INT * AR.x (MASKED), [[ADDRESS]]
|
||||
; EG: MOV * T(0 + AR.x).X+, [[RES]]
|
||||
|
||||
; SI: buffer_store_byte
|
||||
|
||||
define void @store_i8(i8 addrspace(0)* %out, i8 %in) {
|
||||
entry:
|
||||
store i8 %in, i8 addrspace(0)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; i16 store
|
||||
; FUNC-LABEL: {{^}}store_i16:
|
||||
; EG: LSHR * [[ADDRESS:T[0-9]\.[XYZW]]], KC0[2].Y, literal.x
|
||||
; EG-NEXT: 2
|
||||
; EG: MOVA_INT * AR.x (MASKED)
|
||||
; EG: MOV [[OLD:T[0-9]\.[XYZW]]], {{.*}}AR.x
|
||||
|
||||
; IG 0: Get the byte index and truncate the value
|
||||
; EG: AND_INT * T{{[0-9]}}.[[BI_CHAN:[XYZW]]], KC0[2].Y, literal.x
|
||||
; EG: LSHL * T{{[0-9]}}.[[SHIFT_CHAN:[XYZW]]], PV.[[BI_CHAN]], literal.x
|
||||
; EG-NEXT: 3(4.203895e-45)
|
||||
; EG: AND_INT * T{{[0-9]}}.[[TRUNC_CHAN:[XYZW]]], KC0[2].Z, literal.x
|
||||
; EG-NEXT: 65535(9.183409e-41)
|
||||
|
||||
; EG: NOT_INT
|
||||
; EG: AND_INT {{[\* ]*}}[[CLR_CHAN:T[0-9]\.[XYZW]]], {{.*}}[[OLD]]
|
||||
; EG: OR_INT * [[RES:T[0-9]\.[XYZW]]]
|
||||
; TODO: Is the reload necessary?
|
||||
; EG: MOVA_INT * AR.x (MASKED), [[ADDRESS]]
|
||||
; EG: MOV * T(0 + AR.x).X+, [[RES]]
|
||||
|
||||
; SI: buffer_store_short
|
||||
define void @store_i16(i16 addrspace(0)* %out, i16 %in) {
|
||||
entry:
|
||||
store i16 %in, i16 addrspace(0)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}store_i24:
|
||||
; SI: s_lshr_b32 s{{[0-9]+}}, s{{[0-9]+}}, 16
|
||||
; SI-DAG: buffer_store_byte
|
||||
; SI-DAG: buffer_store_short
|
||||
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store can be eliminated
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store can be eliminated
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
define void @store_i24(i24 addrspace(0)* %out, i24 %in) {
|
||||
entry:
|
||||
store i24 %in, i24 addrspace(0)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}store_i25:
|
||||
; SI: s_and_b32 [[AND:s[0-9]+]], s{{[0-9]+}}, 0x1ffffff{{$}}
|
||||
; SI: v_mov_b32_e32 [[VAND:v[0-9]+]], [[AND]]
|
||||
; SI: buffer_store_dword [[VAND]]
|
||||
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG-NOT: MOVA_INT
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM-NOT: MOVA_INT
|
||||
define void @store_i25(i25 addrspace(0)* %out, i25 %in) {
|
||||
entry:
|
||||
store i25 %in, i25 addrspace(0)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}store_v2i8:
|
||||
; v2i8 is naturally 2B aligned, treat as i16
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG-NOT: MOVA_INT
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM-NOT: MOVA_INT
|
||||
|
||||
; SI: buffer_store_short
|
||||
define void @store_v2i8(<2 x i8> addrspace(0)* %out, <2 x i32> %in) {
|
||||
entry:
|
||||
%0 = trunc <2 x i32> %in to <2 x i8>
|
||||
store <2 x i8> %0, <2 x i8> addrspace(0)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}store_v2i8_unaligned:
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; SI: buffer_store_byte
|
||||
define void @store_v2i8_unaligned(<2 x i8> addrspace(0)* %out, <2 x i32> %in) {
|
||||
entry:
|
||||
%0 = trunc <2 x i32> %in to <2 x i8>
|
||||
store <2 x i8> %0, <2 x i8> addrspace(0)* %out, align 1
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
; FUNC-LABEL: {{^}}store_v2i16:
|
||||
; v2i8 is naturally 2B aligned, treat as i16
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG-NOT: MOVA_INT
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM-NOT: MOVA_INT
|
||||
|
||||
; SI: buffer_store_dword
|
||||
define void @store_v2i16(<2 x i16> addrspace(0)* %out, <2 x i32> %in) {
|
||||
entry:
|
||||
%0 = trunc <2 x i32> %in to <2 x i16>
|
||||
store <2 x i16> %0, <2 x i16> addrspace(0)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}store_v2i16_unaligned:
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; SI: buffer_store_short
|
||||
; SI: buffer_store_short
|
||||
define void @store_v2i16_unaligned(<2 x i16> addrspace(0)* %out, <2 x i32> %in) {
|
||||
entry:
|
||||
%0 = trunc <2 x i32> %in to <2 x i16>
|
||||
store <2 x i16> %0, <2 x i16> addrspace(0)* %out, align 2
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}store_v4i8:
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG-NOT: MOVA_INT
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM-NOT: MOVA_INT
|
||||
|
||||
; SI: buffer_store_dword
|
||||
define void @store_v4i8(<4 x i8> addrspace(0)* %out, <4 x i32> %in) {
|
||||
entry:
|
||||
%0 = trunc <4 x i32> %in to <4 x i8>
|
||||
store <4 x i8> %0, <4 x i8> addrspace(0)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}store_v4i8_unaligned:
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; SI: buffer_store_byte
|
||||
; SI: buffer_store_byte
|
||||
; SI: buffer_store_byte
|
||||
; SI: buffer_store_byte
|
||||
; SI-NOT: buffer_store_dword
|
||||
define void @store_v4i8_unaligned(<4 x i8> addrspace(0)* %out, <4 x i32> %in) {
|
||||
entry:
|
||||
%0 = trunc <4 x i32> %in to <4 x i8>
|
||||
store <4 x i8> %0, <4 x i8> addrspace(0)* %out, align 1
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}store_v8i8_unaligned:
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; SI: buffer_store_byte
|
||||
; SI: buffer_store_byte
|
||||
; SI: buffer_store_byte
|
||||
; SI: buffer_store_byte
|
||||
; SI: buffer_store_byte
|
||||
; SI: buffer_store_byte
|
||||
; SI: buffer_store_byte
|
||||
; SI: buffer_store_byte
|
||||
; SI-NOT: buffer_store_dword
|
||||
define void @store_v8i8_unaligned(<8 x i8> addrspace(0)* %out, <8 x i32> %in) {
|
||||
entry:
|
||||
%0 = trunc <8 x i32> %in to <8 x i8>
|
||||
store <8 x i8> %0, <8 x i8> addrspace(0)* %out, align 1
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}store_v4i8_halfaligned:
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; TODO: This load and store cannot be eliminated,
|
||||
; they might be different locations
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; SI: buffer_store_short
|
||||
; SI: buffer_store_short
|
||||
; SI-NOT: buffer_store_dword
|
||||
define void @store_v4i8_halfaligned(<4 x i8> addrspace(0)* %out, <4 x i32> %in) {
|
||||
entry:
|
||||
%0 = trunc <4 x i32> %in to <4 x i8>
|
||||
store <4 x i8> %0, <4 x i8> addrspace(0)* %out, align 2
|
||||
ret void
|
||||
}
|
||||
|
||||
; floating-point store
|
||||
; FUNC-LABEL: {{^}}store_f32:
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; SI: buffer_store_dword
|
||||
|
||||
define void @store_f32(float addrspace(0)* %out, float %in) {
|
||||
store float %in, float addrspace(0)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}store_v4i16:
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
;TODO: why not x2?
|
||||
; XSI: buffer_store_dwordx2
|
||||
; SI: buffer_store_dword
|
||||
; SI: buffer_store_dword
|
||||
define void @store_v4i16(<4 x i16> addrspace(0)* %out, <4 x i32> %in) {
|
||||
entry:
|
||||
%0 = trunc <4 x i32> %in to <4 x i16>
|
||||
store <4 x i16> %0, <4 x i16> addrspace(0)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; vec2 floating-point stores
|
||||
; FUNC-LABEL: {{^}}store_v2f32:
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
;TODO: why not x2?
|
||||
; XSI: buffer_store_dwordx2
|
||||
; SI: buffer_store_dword
|
||||
; SI: buffer_store_dword
|
||||
|
||||
define void @store_v2f32(<2 x float> addrspace(0)* %out, float %a, float %b) {
|
||||
entry:
|
||||
%0 = insertelement <2 x float> <float 0.0, float 0.0>, float %a, i32 0
|
||||
%1 = insertelement <2 x float> %0, float %b, i32 1
|
||||
store <2 x float> %1, <2 x float> addrspace(0)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}store_v3i32:
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
;TODO: why not x2?
|
||||
; XSI-DAG: buffer_store_dwordx2
|
||||
; SI: buffer_store_dword
|
||||
; SI: buffer_store_dword
|
||||
; SI: buffer_store_dword
|
||||
|
||||
define void @store_v3i32(<3 x i32> addrspace(0)* %out, <3 x i32> %a) nounwind {
|
||||
store <3 x i32> %a, <3 x i32> addrspace(0)* %out, align 16
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}store_v4i32:
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
;TODO: why not x4?
|
||||
; XSI: buffer_store_dwordx4
|
||||
; SI: buffer_store_dword
|
||||
; SI: buffer_store_dword
|
||||
; SI: buffer_store_dword
|
||||
; SI: buffer_store_dword
|
||||
define void @store_v4i32(<4 x i32> addrspace(0)* %out, <4 x i32> %in) {
|
||||
entry:
|
||||
store <4 x i32> %in, <4 x i32> addrspace(0)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}store_v4i32_unaligned:
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
;TODO: why not x4?
|
||||
; XSI: buffer_store_dwordx4
|
||||
; SI: buffer_store_dword
|
||||
; SI: buffer_store_dword
|
||||
; SI: buffer_store_dword
|
||||
; SI: buffer_store_dword
|
||||
define void @store_v4i32_unaligned(<4 x i32> addrspace(0)* %out, <4 x i32> %in) {
|
||||
entry:
|
||||
store <4 x i32> %in, <4 x i32> addrspace(0)* %out, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
; v4f32 store
|
||||
; FUNC-LABEL: {{^}}store_v4f32:
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
;TODO: why not x4?
|
||||
; XSI: buffer_store_dwordx4
|
||||
; SI: buffer_store_dword
|
||||
; SI: buffer_store_dword
|
||||
; SI: buffer_store_dword
|
||||
; SI: buffer_store_dword
|
||||
define void @store_v4f32(<4 x float> addrspace(0)* %out, <4 x float> addrspace(0)* %in) {
|
||||
%1 = load <4 x float>, <4 x float> addrspace(0) * %in
|
||||
store <4 x float> %1, <4 x float> addrspace(0)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}store_i64_i8:
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; SI: buffer_store_byte
|
||||
define void @store_i64_i8(i8 addrspace(0)* %out, i64 %in) {
|
||||
entry:
|
||||
%0 = trunc i64 %in to i8
|
||||
store i8 %0, i8 addrspace(0)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}store_i64_i16:
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}{{T[0-9]+\.[XYZW]}}, T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; SI: buffer_store_short
|
||||
define void @store_i64_i16(i16 addrspace(0)* %out, i64 %in) {
|
||||
entry:
|
||||
%0 = trunc i64 %in to i16
|
||||
store i16 %0, i16 addrspace(0)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; The stores in this function are combined by the optimizer to create a
|
||||
; 64-bit store with 32-bit alignment. This is legal and the legalizer
|
||||
; should not try to split the 64-bit store back into 2 32-bit stores.
|
||||
|
||||
; FUNC-LABEL: {{^}}vecload2:
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
;TODO: why not x2?
|
||||
; XSI: buffer_store_dwordx2
|
||||
; SI: buffer_store_dword
|
||||
; SI: buffer_store_dword
|
||||
define void @vecload2(i32 addrspace(0)* nocapture %out, i32 addrspace(2)* nocapture %mem) #0 {
|
||||
entry:
|
||||
%0 = load i32, i32 addrspace(2)* %mem, align 4
|
||||
%arrayidx1.i = getelementptr inbounds i32, i32 addrspace(2)* %mem, i64 1
|
||||
%1 = load i32, i32 addrspace(2)* %arrayidx1.i, align 4
|
||||
store i32 %0, i32 addrspace(0)* %out, align 4
|
||||
%arrayidx1 = getelementptr inbounds i32, i32 addrspace(0)* %out, i64 1
|
||||
store i32 %1, i32 addrspace(0)* %arrayidx1, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
; When i128 was a legal type this program generated cannot select errors:
|
||||
|
||||
; FUNC-LABEL: {{^}}"i128-const-store":
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; EG: MOVA_INT
|
||||
; EG: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
; CM: MOVA_INT
|
||||
; CM: MOV {{[\* ]*}}T(0 + AR.x).X+,
|
||||
|
||||
;TODO: why not x4?
|
||||
; XSI: buffer_store_dwordx4
|
||||
; SI: buffer_store_dword
|
||||
; SI: buffer_store_dword
|
||||
; SI: buffer_store_dword
|
||||
; SI: buffer_store_dword
|
||||
define void @i128-const-store(i32 addrspace(0)* %out) {
|
||||
entry:
|
||||
store i32 1, i32 addrspace(0)* %out, align 4
|
||||
%arrayidx2 = getelementptr inbounds i32, i32 addrspace(0)* %out, i64 1
|
||||
store i32 1, i32 addrspace(0)* %arrayidx2, align 4
|
||||
%arrayidx4 = getelementptr inbounds i32, i32 addrspace(0)* %out, i64 2
|
||||
store i32 2, i32 addrspace(0)* %arrayidx4, align 4
|
||||
%arrayidx6 = getelementptr inbounds i32, i32 addrspace(0)* %out, i64 3
|
||||
store i32 2, i32 addrspace(0)* %arrayidx6, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
attributes #0 = { nounwind }
|
||||
Reference in New Issue
Block a user