diff options
| author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2018-08-08 17:00:09 +0000 |
|---|---|---|
| committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2018-08-08 17:00:09 +0000 |
| commit | 1df7059150a1f5e8c2681eb93c5904ab3f844096 (patch) | |
| tree | a4deac594bb353d71072368d78b9710fd6b30f71 | |
| parent | 935f3b70fe36528a59000808a327c801cf15eeea (diff) | |
| download | bcm5719-llvm-1df7059150a1f5e8c2681eb93c5904ab3f844096.tar.gz bcm5719-llvm-1df7059150a1f5e8c2681eb93c5904ab3f844096.zip | |
[Hexagon] Diagnose misaligned absolute loads and stores
Differential Revision: https://reviews.llvm.org/D50405
llvm-svn: 339272
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelLowering.cpp | 89 | ||||
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelLowering.h | 8 | ||||
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonPatterns.td | 205 | ||||
| -rw-r--r-- | llvm/test/CodeGen/Hexagon/misaligned-const-load.ll | 38 | ||||
| -rw-r--r-- | llvm/test/CodeGen/Hexagon/misaligned-const-store.ll | 38 |
5 files changed, 286 insertions, 92 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp index 604d84994b6..4c28b6dc4a8 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -151,16 +151,6 @@ static bool CC_SkipOdd(unsigned &ValNo, MVT &ValVT, MVT &LocVT, #include "HexagonGenCallingConv.inc" -void HexagonTargetLowering::promoteLdStType(MVT VT, MVT PromotedLdStVT) { - if (VT != PromotedLdStVT) { - setOperationAction(ISD::LOAD, VT, Promote); - AddPromotedToType(ISD::LOAD, VT, PromotedLdStVT); - - setOperationAction(ISD::STORE, VT, Promote); - AddPromotedToType(ISD::STORE, VT, PromotedLdStVT); - } -} - SDValue HexagonTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const { @@ -1403,12 +1393,6 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, // Handling of vector operations. // - promoteLdStType(MVT::v4i8, MVT::i32); - promoteLdStType(MVT::v2i16, MVT::i32); - promoteLdStType(MVT::v8i8, MVT::i64); - promoteLdStType(MVT::v4i16, MVT::i64); - promoteLdStType(MVT::v2i32, MVT::i64); - // Set the action for vector operations to "expand", then override it with // either "custom" or "legal" for specific cases. static const unsigned VectExpOps[] = { @@ -1488,9 +1472,13 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, } // Custom lower unaligned loads. - for (MVT VecVT : {MVT::i32, MVT::v4i8, MVT::i64, MVT::v8i8, - MVT::v2i16, MVT::v4i16, MVT::v2i32}) { - setOperationAction(ISD::LOAD, VecVT, Custom); + // Also, for both loads and stores, verify the alignment of the address + // in case it is a compile-time constant. This is a usability feature to + // provide a meaningful error message to users. + for (MVT VT : {MVT::i16, MVT::i32, MVT::v4i8, MVT::i64, MVT::v8i8, + MVT::v2i16, MVT::v4i16, MVT::v2i32}) { + setOperationAction(ISD::LOAD, VT, Custom); + setOperationAction(ISD::STORE, VT, Custom); } for (MVT VT : {MVT::v2i16, MVT::v4i8, MVT::v2i32, MVT::v4i16, MVT::v2i32}) { @@ -1738,6 +1726,26 @@ const char* HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const { return nullptr; } +void +HexagonTargetLowering::validateConstPtrAlignment(SDValue Ptr, const SDLoc &dl, + unsigned NeedAlign) const { + auto *CA = dyn_cast<ConstantSDNode>(Ptr); + if (!CA) + return; + unsigned Addr = CA->getZExtValue(); + unsigned HaveAlign = Addr != 0 ? 1u << countTrailingZeros(Addr) : NeedAlign; + if (HaveAlign < NeedAlign) { + std::string ErrMsg; + raw_string_ostream O(ErrMsg); + O << "Misaligned constant address: " << format_hex(Addr, 10) + << " has alignment " << HaveAlign + << ", but the memory access requires " << NeedAlign; + if (DebugLoc DL = dl.getDebugLoc()) + DL.print(O << ", at "); + report_fatal_error(O.str()); + } +} + // Bit-reverse Load Intrinsic: Check if the instruction is a bit reverse load // intrinsic. static bool isBrevLdIntrinsic(const Value *Inst) { @@ -2643,12 +2651,37 @@ HexagonTargetLowering::allowTruncateForTailCall(Type *Ty1, Type *Ty2) const { } SDValue +HexagonTargetLowering::LowerLoad(SDValue Op, SelectionDAG &DAG) const { + LoadSDNode *LN = cast<LoadSDNode>(Op.getNode()); + unsigned ClaimAlign = LN->getAlignment(); + validateConstPtrAlignment(LN->getBasePtr(), SDLoc(Op), ClaimAlign); + // Call LowerUnalignedLoad for all loads, it recognizes loads that + // don't need extra aligning. + return LowerUnalignedLoad(Op, DAG); +} + +SDValue +HexagonTargetLowering::LowerStore(SDValue Op, SelectionDAG &DAG) const { + StoreSDNode *SN = cast<StoreSDNode>(Op.getNode()); + unsigned ClaimAlign = SN->getAlignment(); + SDValue Ptr = SN->getBasePtr(); + const SDLoc &dl(Op); + validateConstPtrAlignment(Ptr, dl, ClaimAlign); + + MVT StoreTy = SN->getMemoryVT().getSimpleVT(); + unsigned NeedAlign = Subtarget.getTypeAlignment(StoreTy); + if (ClaimAlign < NeedAlign) + return expandUnalignedStore(SN, DAG); + return Op; +} + +SDValue HexagonTargetLowering::LowerUnalignedLoad(SDValue Op, SelectionDAG &DAG) const { LoadSDNode *LN = cast<LoadSDNode>(Op.getNode()); - unsigned HaveAlign = LN->getAlignment(); MVT LoadTy = ty(Op); unsigned NeedAlign = Subtarget.getTypeAlignment(LoadTy); + unsigned HaveAlign = LN->getAlignment(); if (HaveAlign >= NeedAlign) return Op; @@ -2802,7 +2835,8 @@ HexagonTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG); case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG); case ISD::BITCAST: return LowerBITCAST(Op, DAG); - case ISD::LOAD: return LowerUnalignedLoad(Op, DAG); + case ISD::LOAD: return LowerLoad(Op, DAG); + case ISD::STORE: return LowerStore(Op, DAG); case ISD::ADDCARRY: case ISD::SUBCARRY: return LowerAddSubCarry(Op, DAG); case ISD::SRA: @@ -2834,6 +2868,19 @@ HexagonTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { } void +HexagonTargetLowering::LowerOperationWrapper(SDNode *N, + SmallVectorImpl<SDValue> &Results, + SelectionDAG &DAG) const { + // We are only custom-lowering stores to verify the alignment of the + // address if it is a compile-time constant. Since a store can be modified + // during type-legalization (the value being stored may need legalization), + // return empty Results here to indicate that we don't really make any + // changes in the custom lowering. + if (N->getOpcode() != ISD::STORE) + return TargetLowering::LowerOperationWrapper(N, Results, DAG); +} + +void HexagonTargetLowering::ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, SelectionDAG &DAG) const { diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h index 3d94bd1ff6e..376d68c67b5 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h @@ -101,7 +101,6 @@ namespace HexagonISD { bool CanReturnSmallStruct(const Function* CalleeFn, unsigned& RetSize) const; - void promoteLdStType(MVT VT, MVT PromotedLdStVT); public: explicit HexagonTargetLowering(const TargetMachine &TM, @@ -146,6 +145,8 @@ namespace HexagonISD { const override; SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; + void LowerOperationWrapper(SDNode *N, SmallVectorImpl<SDValue> &Results, + SelectionDAG &DAG) const override; void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, SelectionDAG &DAG) const override; @@ -164,6 +165,8 @@ namespace HexagonISD { SDValue LowerANY_EXTEND(SDValue Op, SelectionDAG &DAG) const; SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) const; SDValue LowerZERO_EXTEND(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerLoad(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerStore(SDValue Op, SelectionDAG &DAG) const; SDValue LowerUnalignedLoad(SDValue Op, SelectionDAG &DAG) const; SDValue LowerAddSubCarry(SDValue Op, SelectionDAG &DAG) const; @@ -314,6 +317,9 @@ namespace HexagonISD { private: void initializeHVXLowering(); + void validateConstPtrAlignment(SDValue Ptr, const SDLoc &dl, + unsigned NeedAlign) const; + std::pair<SDValue,int> getBaseAndOffset(SDValue Addr) const; bool getBuildVectorConstInts(ArrayRef<SDValue> Values, MVT VecTy, diff --git a/llvm/lib/Target/Hexagon/HexagonPatterns.td b/llvm/lib/Target/Hexagon/HexagonPatterns.td index 384fda4ce39..198405d37b8 100644 --- a/llvm/lib/Target/Hexagon/HexagonPatterns.td +++ b/llvm/lib/Target/Hexagon/HexagonPatterns.td @@ -2306,16 +2306,26 @@ let AddedComplexity = 140 in { // GP-relative address let AddedComplexity = 120 in { - def: Storea_pat<truncstorei8, I32, addrgp, S2_storerbgp>; - def: Storea_pat<truncstorei16, I32, addrgp, S2_storerhgp>; - def: Storea_pat<store, I32, addrgp, S2_storerigp>; - def: Storea_pat<store, I64, addrgp, S2_storerdgp>; - def: Storea_pat<store, F32, addrgp, S2_storerigp>; - def: Storea_pat<store, F64, addrgp, S2_storerdgp>; - def: Storea_pat<AtomSt<atomic_store_8>, I32, addrgp, S2_storerbgp>; - def: Storea_pat<AtomSt<atomic_store_16>, I32, addrgp, S2_storerhgp>; - def: Storea_pat<AtomSt<atomic_store_32>, I32, addrgp, S2_storerigp>; - def: Storea_pat<AtomSt<atomic_store_64>, I64, addrgp, S2_storerdgp>; + def: Storea_pat<truncstorei8, I32, addrgp, S2_storerbgp>; + def: Storea_pat<truncstorei16, I32, addrgp, S2_storerhgp>; + def: Storea_pat<store, I32, addrgp, S2_storerigp>; + def: Storea_pat<store, V4I8, addrgp, S2_storerigp>; + def: Storea_pat<store, V2I16, addrgp, S2_storerigp>; + def: Storea_pat<store, I64, addrgp, S2_storerdgp>; + def: Storea_pat<store, V8I8, addrgp, S2_storerdgp>; + def: Storea_pat<store, V4I16, addrgp, S2_storerdgp>; + def: Storea_pat<store, V2I32, addrgp, S2_storerdgp>; + def: Storea_pat<store, F32, addrgp, S2_storerigp>; + def: Storea_pat<store, F64, addrgp, S2_storerdgp>; + def: Storea_pat<AtomSt<atomic_store_8>, I32, addrgp, S2_storerbgp>; + def: Storea_pat<AtomSt<atomic_store_16>, I32, addrgp, S2_storerhgp>; + def: Storea_pat<AtomSt<atomic_store_32>, I32, addrgp, S2_storerigp>; + def: Storea_pat<AtomSt<atomic_store_32>, V4I8, addrgp, S2_storerigp>; + def: Storea_pat<AtomSt<atomic_store_32>, V2I16, addrgp, S2_storerigp>; + def: Storea_pat<AtomSt<atomic_store_64>, I64, addrgp, S2_storerdgp>; + def: Storea_pat<AtomSt<atomic_store_64>, V8I8, addrgp, S2_storerdgp>; + def: Storea_pat<AtomSt<atomic_store_64>, V4I16, addrgp, S2_storerdgp>; + def: Storea_pat<AtomSt<atomic_store_64>, V2I32, addrgp, S2_storerdgp>; def: Stoream_pat<truncstorei8, I64, addrgp, LoReg, S2_storerbgp>; def: Stoream_pat<truncstorei16, I64, addrgp, LoReg, S2_storerhgp>; @@ -2325,16 +2335,26 @@ let AddedComplexity = 120 in { // Absolute address let AddedComplexity = 110 in { - def: Storea_pat<truncstorei8, I32, anyimm0, PS_storerbabs>; - def: Storea_pat<truncstorei16, I32, anyimm1, PS_storerhabs>; - def: Storea_pat<store, I32, anyimm2, PS_storeriabs>; - def: Storea_pat<store, I64, anyimm3, PS_storerdabs>; - def: Storea_pat<store, F32, anyimm2, PS_storeriabs>; - def: Storea_pat<store, F64, anyimm3, PS_storerdabs>; - def: Storea_pat<AtomSt<atomic_store_8>, I32, anyimm0, PS_storerbabs>; - def: Storea_pat<AtomSt<atomic_store_16>, I32, anyimm1, PS_storerhabs>; - def: Storea_pat<AtomSt<atomic_store_32>, I32, anyimm2, PS_storeriabs>; - def: Storea_pat<AtomSt<atomic_store_64>, I64, anyimm3, PS_storerdabs>; + def: Storea_pat<truncstorei8, I32, anyimm0, PS_storerbabs>; + def: Storea_pat<truncstorei16, I32, anyimm1, PS_storerhabs>; + def: Storea_pat<store, I32, anyimm2, PS_storeriabs>; + def: Storea_pat<store, V4I8, anyimm2, PS_storeriabs>; + def: Storea_pat<store, V2I16, anyimm2, PS_storeriabs>; + def: Storea_pat<store, I64, anyimm3, PS_storerdabs>; + def: Storea_pat<store, V8I8, anyimm3, PS_storerdabs>; + def: Storea_pat<store, V4I16, anyimm3, PS_storerdabs>; + def: Storea_pat<store, V2I32, anyimm3, PS_storerdabs>; + def: Storea_pat<store, F32, anyimm2, PS_storeriabs>; + def: Storea_pat<store, F64, anyimm3, PS_storerdabs>; + def: Storea_pat<AtomSt<atomic_store_8>, I32, anyimm0, PS_storerbabs>; + def: Storea_pat<AtomSt<atomic_store_16>, I32, anyimm1, PS_storerhabs>; + def: Storea_pat<AtomSt<atomic_store_32>, I32, anyimm2, PS_storeriabs>; + def: Storea_pat<AtomSt<atomic_store_32>, V4I8, anyimm2, PS_storeriabs>; + def: Storea_pat<AtomSt<atomic_store_32>, V2I16, anyimm2, PS_storeriabs>; + def: Storea_pat<AtomSt<atomic_store_64>, I64, anyimm3, PS_storerdabs>; + def: Storea_pat<AtomSt<atomic_store_64>, V8I8, anyimm3, PS_storerdabs>; + def: Storea_pat<AtomSt<atomic_store_64>, V4I16, anyimm3, PS_storerdabs>; + def: Storea_pat<AtomSt<atomic_store_64>, V2I32, anyimm3, PS_storerdabs>; def: Stoream_pat<truncstorei8, I64, anyimm0, LoReg, PS_storerbabs>; def: Stoream_pat<truncstorei16, I64, anyimm1, LoReg, PS_storerhabs>; @@ -2344,12 +2364,17 @@ let AddedComplexity = 110 in { // Reg<<S + Imm let AddedComplexity = 100 in { - def: Storexu_shl_pat<truncstorei8, I32, anyimm0, S4_storerb_ur>; - def: Storexu_shl_pat<truncstorei16, I32, anyimm1, S4_storerh_ur>; - def: Storexu_shl_pat<store, I32, anyimm2, S4_storeri_ur>; - def: Storexu_shl_pat<store, I64, anyimm3, S4_storerd_ur>; - def: Storexu_shl_pat<store, F32, anyimm2, S4_storeri_ur>; - def: Storexu_shl_pat<store, F64, anyimm3, S4_storerd_ur>; + def: Storexu_shl_pat<truncstorei8, I32, anyimm0, S4_storerb_ur>; + def: Storexu_shl_pat<truncstorei16, I32, anyimm1, S4_storerh_ur>; + def: Storexu_shl_pat<store, I32, anyimm2, S4_storeri_ur>; + def: Storexu_shl_pat<store, V4I8, anyimm2, S4_storeri_ur>; + def: Storexu_shl_pat<store, V2I16, anyimm2, S4_storeri_ur>; + def: Storexu_shl_pat<store, I64, anyimm3, S4_storerd_ur>; + def: Storexu_shl_pat<store, V8I8, anyimm3, S4_storerd_ur>; + def: Storexu_shl_pat<store, V4I16, anyimm3, S4_storerd_ur>; + def: Storexu_shl_pat<store, V2I32, anyimm3, S4_storerd_ur>; + def: Storexu_shl_pat<store, F32, anyimm2, S4_storeri_ur>; + def: Storexu_shl_pat<store, F64, anyimm3, S4_storerd_ur>; def: Pat<(store I1:$Pu, (add (shl I32:$Rs, u2_0ImmPred:$u2), anyimm:$A)), (S4_storerb_ur IntRegs:$Rs, imm:$u2, imm:$A, (I1toI32 I1:$Pu))>; @@ -2357,12 +2382,17 @@ let AddedComplexity = 100 in { // Reg<<S + Reg let AddedComplexity = 90 in { - def: Storexr_shl_pat<truncstorei8, I32, S4_storerb_rr>; - def: Storexr_shl_pat<truncstorei16, I32, S4_storerh_rr>; - def: Storexr_shl_pat<store, I32, S4_storeri_rr>; - def: Storexr_shl_pat<store, I64, S4_storerd_rr>; - def: Storexr_shl_pat<store, F32, S4_storeri_rr>; - def: Storexr_shl_pat<store, F64, S4_storerd_rr>; + def: Storexr_shl_pat<truncstorei8, I32, S4_storerb_rr>; + def: Storexr_shl_pat<truncstorei16, I32, S4_storerh_rr>; + def: Storexr_shl_pat<store, I32, S4_storeri_rr>; + def: Storexr_shl_pat<store, V4I8, S4_storeri_rr>; + def: Storexr_shl_pat<store, V2I16, S4_storeri_rr>; + def: Storexr_shl_pat<store, I64, S4_storerd_rr>; + def: Storexr_shl_pat<store, V8I8, S4_storerd_rr>; + def: Storexr_shl_pat<store, V4I16, S4_storerd_rr>; + def: Storexr_shl_pat<store, V2I32, S4_storerd_rr>; + def: Storexr_shl_pat<store, F32, S4_storeri_rr>; + def: Storexr_shl_pat<store, F64, S4_storerd_rr>; def: Pat<(store I1:$Pu, (add (shl I32:$Rs, u2_0ImmPred:$u2), I32:$Rt)), (S4_storerb_ur IntRegs:$Rt, IntRegs:$Rs, imm:$u2, (I1toI32 I1:$Pu))>; @@ -2414,20 +2444,30 @@ let AddedComplexity = 70 in { // Fi+Imm, Fi, store-register let AddedComplexity = 60 in { - defm: Storexi_fi_add_pat<truncstorei8, I32, anyimm, S2_storerb_io>; - defm: Storexi_fi_add_pat<truncstorei16, I32, anyimm, S2_storerh_io>; - defm: Storexi_fi_add_pat<store, I32, anyimm, S2_storeri_io>; - defm: Storexi_fi_add_pat<store, I64, anyimm, S2_storerd_io>; - defm: Storexi_fi_add_pat<store, F32, anyimm, S2_storeri_io>; - defm: Storexi_fi_add_pat<store, F64, anyimm, S2_storerd_io>; + defm: Storexi_fi_add_pat<truncstorei8, I32, anyimm, S2_storerb_io>; + defm: Storexi_fi_add_pat<truncstorei16, I32, anyimm, S2_storerh_io>; + defm: Storexi_fi_add_pat<store, I32, anyimm, S2_storeri_io>; + defm: Storexi_fi_add_pat<store, V4I8, anyimm, S2_storeri_io>; + defm: Storexi_fi_add_pat<store, V2I16, anyimm, S2_storeri_io>; + defm: Storexi_fi_add_pat<store, I64, anyimm, S2_storerd_io>; + defm: Storexi_fi_add_pat<store, V8I8, anyimm, S2_storerd_io>; + defm: Storexi_fi_add_pat<store, V4I16, anyimm, S2_storerd_io>; + defm: Storexi_fi_add_pat<store, V2I32, anyimm, S2_storerd_io>; + defm: Storexi_fi_add_pat<store, F32, anyimm, S2_storeri_io>; + defm: Storexi_fi_add_pat<store, F64, anyimm, S2_storerd_io>; defm: Storexim_fi_add_pat<store, I1, anyimm, I1toI32, S2_storerb_io>; - def: Storexi_fi_pat<truncstorei8, I32, S2_storerb_io>; - def: Storexi_fi_pat<truncstorei16, I32, S2_storerh_io>; - def: Storexi_fi_pat<store, I32, S2_storeri_io>; - def: Storexi_fi_pat<store, I64, S2_storerd_io>; - def: Storexi_fi_pat<store, F32, S2_storeri_io>; - def: Storexi_fi_pat<store, F64, S2_storerd_io>; + def: Storexi_fi_pat<truncstorei8, I32, S2_storerb_io>; + def: Storexi_fi_pat<truncstorei16, I32, S2_storerh_io>; + def: Storexi_fi_pat<store, I32, S2_storeri_io>; + def: Storexi_fi_pat<store, V4I8, S2_storeri_io>; + def: Storexi_fi_pat<store, V2I16, S2_storeri_io>; + def: Storexi_fi_pat<store, I64, S2_storerd_io>; + def: Storexi_fi_pat<store, V8I8, S2_storerd_io>; + def: Storexi_fi_pat<store, V4I16, S2_storerd_io>; + def: Storexi_fi_pat<store, V2I32, S2_storerd_io>; + def: Storexi_fi_pat<store, F32, S2_storeri_io>; + def: Storexi_fi_pat<store, F64, S2_storerd_io>; def: Storexim_fi_pat<store, I1, I1toI32, S2_storerb_io>; } @@ -2452,32 +2492,47 @@ let AddedComplexity = 50 in { // Reg+Imm, store-register let AddedComplexity = 40 in { - defm: Storexi_pat<truncstorei8, I32, anyimm0, S2_storerb_io>; - defm: Storexi_pat<truncstorei16, I32, anyimm1, S2_storerh_io>; - defm: Storexi_pat<store, I32, anyimm2, S2_storeri_io>; - defm: Storexi_pat<store, I64, anyimm3, S2_storerd_io>; - defm: Storexi_pat<store, F32, anyimm2, S2_storeri_io>; - defm: Storexi_pat<store, F64, anyimm3, S2_storerd_io>; + defm: Storexi_pat<truncstorei8, I32, anyimm0, S2_storerb_io>; + defm: Storexi_pat<truncstorei16, I32, anyimm1, S2_storerh_io>; + defm: Storexi_pat<store, I32, anyimm2, S2_storeri_io>; + defm: Storexi_pat<store, V4I8, anyimm2, S2_storeri_io>; + defm: Storexi_pat<store, V2I16, anyimm2, S2_storeri_io>; + defm: Storexi_pat<store, I64, anyimm3, S2_storerd_io>; + defm: Storexi_pat<store, V8I8, anyimm3, S2_storerd_io>; + defm: Storexi_pat<store, V4I16, anyimm3, S2_storerd_io>; + defm: Storexi_pat<store, V2I32, anyimm3, S2_storerd_io>; + defm: Storexi_pat<store, F32, anyimm2, S2_storeri_io>; + defm: Storexi_pat<store, F64, anyimm3, S2_storerd_io>; defm: Storexim_pat<truncstorei8, I64, anyimm0, LoReg, S2_storerb_io>; defm: Storexim_pat<truncstorei16, I64, anyimm1, LoReg, S2_storerh_io>; defm: Storexim_pat<truncstorei32, I64, anyimm2, LoReg, S2_storeri_io>; defm: Storexim_pat<store, I1, anyimm0, I1toI32, S2_storerb_io>; - defm: Storexi_pat<AtomSt<atomic_store_8>, I32, anyimm0, S2_storerb_io>; - defm: Storexi_pat<AtomSt<atomic_store_16>, I32, anyimm1, S2_storerh_io>; - defm: Storexi_pat<AtomSt<atomic_store_32>, I32, anyimm2, S2_storeri_io>; - defm: Storexi_pat<AtomSt<atomic_store_64>, I64, anyimm3, S2_storerd_io>; + defm: Storexi_pat<AtomSt<atomic_store_8>, I32, anyimm0, S2_storerb_io>; + defm: Storexi_pat<AtomSt<atomic_store_16>, I32, anyimm1, S2_storerh_io>; + defm: Storexi_pat<AtomSt<atomic_store_32>, I32, anyimm2, S2_storeri_io>; + defm: Storexi_pat<AtomSt<atomic_store_32>, V4I8, anyimm2, S2_storeri_io>; + defm: Storexi_pat<AtomSt<atomic_store_32>, V2I16, anyimm2, S2_storeri_io>; + defm: Storexi_pat<AtomSt<atomic_store_64>, I64, anyimm3, S2_storerd_io>; + defm: Storexi_pat<AtomSt<atomic_store_64>, V8I8, anyimm3, S2_storerd_io>; + defm: Storexi_pat<AtomSt<atomic_store_64>, V4I16, anyimm3, S2_storerd_io>; + defm: Storexi_pat<AtomSt<atomic_store_64>, V2I32, anyimm3, S2_storerd_io>; } // Reg+Reg let AddedComplexity = 30 in { - def: Storexr_add_pat<truncstorei8, I32, S4_storerb_rr>; - def: Storexr_add_pat<truncstorei16, I32, S4_storerh_rr>; - def: Storexr_add_pat<store, I32, S4_storeri_rr>; - def: Storexr_add_pat<store, I64, S4_storerd_rr>; - def: Storexr_add_pat<store, F32, S4_storeri_rr>; - def: Storexr_add_pat<store, F64, S4_storerd_rr>; + def: Storexr_add_pat<truncstorei8, I32, S4_storerb_rr>; + def: Storexr_add_pat<truncstorei16, I32, S4_storerh_rr>; + def: Storexr_add_pat<store, I32, S4_storeri_rr>; + def: Storexr_add_pat<store, V4I8, S4_storeri_rr>; + def: Storexr_add_pat<store, V2I16, S4_storeri_rr>; + def: Storexr_add_pat<store, I64, S4_storerd_rr>; + def: Storexr_add_pat<store, V8I8, S4_storerd_rr>; + def: Storexr_add_pat<store, V4I16, S4_storerd_rr>; + def: Storexr_add_pat<store, V2I32, S4_storerd_rr>; + def: Storexr_add_pat<store, F32, S4_storeri_rr>; + def: Storexr_add_pat<store, F64, S4_storerd_rr>; def: Pat<(store I1:$Pu, (add I32:$Rs, I32:$Rt)), (S4_storerb_rr IntRegs:$Rs, IntRegs:$Rt, 0, (I1toI32 I1:$Pu))>; @@ -2496,22 +2551,32 @@ let AddedComplexity = 20 in { // Reg, store-register let AddedComplexity = 10 in { - def: Storexi_base_pat<truncstorei8, I32, S2_storerb_io>; - def: Storexi_base_pat<truncstorei16, I32, S2_storerh_io>; - def: Storexi_base_pat<store, I32, S2_storeri_io>; - def: Storexi_base_pat<store, I64, S2_storerd_io>; - def: Storexi_base_pat<store, F32, S2_storeri_io>; - def: Storexi_base_pat<store, F64, S2_storerd_io>; + def: Storexi_base_pat<truncstorei8, I32, S2_storerb_io>; + def: Storexi_base_pat<truncstorei16, I32, S2_storerh_io>; + def: Storexi_base_pat<store, I32, S2_storeri_io>; + def: Storexi_base_pat<store, V4I8, S2_storeri_io>; + def: Storexi_base_pat<store, V2I16, S2_storeri_io>; + def: Storexi_base_pat<store, I64, S2_storerd_io>; + def: Storexi_base_pat<store, V8I8, S2_storerd_io>; + def: Storexi_base_pat<store, V4I16, S2_storerd_io>; + def: Storexi_base_pat<store, V2I32, S2_storerd_io>; + def: Storexi_base_pat<store, F32, S2_storeri_io>; + def: Storexi_base_pat<store, F64, S2_storerd_io>; def: Storexim_base_pat<truncstorei8, I64, LoReg, S2_storerb_io>; def: Storexim_base_pat<truncstorei16, I64, LoReg, S2_storerh_io>; def: Storexim_base_pat<truncstorei32, I64, LoReg, S2_storeri_io>; def: Storexim_base_pat<store, I1, I1toI32, S2_storerb_io>; - def: Storexi_base_pat<AtomSt<atomic_store_8>, I32, S2_storerb_io>; - def: Storexi_base_pat<AtomSt<atomic_store_16>, I32, S2_storerh_io>; - def: Storexi_base_pat<AtomSt<atomic_store_32>, I32, S2_storeri_io>; - def: Storexi_base_pat<AtomSt<atomic_store_64>, I64, S2_storerd_io>; + def: Storexi_base_pat<AtomSt<atomic_store_8>, I32, S2_storerb_io>; + def: Storexi_base_pat<AtomSt<atomic_store_16>, I32, S2_storerh_io>; + def: Storexi_base_pat<AtomSt<atomic_store_32>, I32, S2_storeri_io>; + def: Storexi_base_pat<AtomSt<atomic_store_32>, V4I8, S2_storeri_io>; + def: Storexi_base_pat<AtomSt<atomic_store_32>, V2I16, S2_storeri_io>; + def: Storexi_base_pat<AtomSt<atomic_store_64>, I64, S2_storerd_io>; + def: Storexi_base_pat<AtomSt<atomic_store_64>, V8I8, S2_storerd_io>; + def: Storexi_base_pat<AtomSt<atomic_store_64>, V4I16, S2_storerd_io>; + def: Storexi_base_pat<AtomSt<atomic_store_64>, V2I32, S2_storerd_io>; } diff --git a/llvm/test/CodeGen/Hexagon/misaligned-const-load.ll b/llvm/test/CodeGen/Hexagon/misaligned-const-load.ll new file mode 100644 index 00000000000..0a437964cc7 --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/misaligned-const-load.ll @@ -0,0 +1,38 @@ +; RUN: not llc -march=hexagon < %s 2>&1 | FileCheck %s + +; Check that the misaligned load is diagnosed. +; CHECK: LLVM ERROR: Misaligned constant address: 0x00012345 has alignment 1, but the memory access requires 4, at misaligned-const-load.c:2:10 + +target triple = "hexagon" + +define i32 @bad_load() #0 !dbg !10 { +entry: + %0 = load i32, i32* inttoptr (i32 74565 to i32*), align 4, !dbg !13, !tbaa !14 + ret i32 %0, !dbg !18 +} + +attributes #0 = { norecurse nounwind readonly "target-cpu"="hexagonv60" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 (http://llvm.org/git/clang.git 3fb90d137ea16e5c3a4580b9db5fd18d93df1a90) (http://llvm.org/git/llvm.git daf385e5698c00fdd693fac736acc96b95ccccd3)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3) +!1 = !DIFile(filename: "misaligned-const-load.c", directory: "/test") +!2 = !{} +!3 = !{!4} +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 32) +!5 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!6 = !{i32 2, !"Dwarf Version", i32 4} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i32 1, !"wchar_size", i32 4} +!9 = !{!"clang version 8.0.0 (http://llvm.org/git/clang.git 3fb90d137ea16e5c3a4580b9db5fd18d93df1a90) (http://llvm.org/git/llvm.git daf385e5698c00fdd693fac736acc96b95ccccd3)"} +!10 = distinct !DISubprogram(name: "bad_load", scope: !1, file: !1, line: 1, type: !11, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: true, unit: !0, retainedNodes: !2) +!11 = !DISubroutineType(types: !12) +!12 = !{!5} +!13 = !DILocation(line: 2, column: 10, scope: !10) +!14 = !{!15, !15, i64 0} +!15 = !{!"int", !16, i64 0} +!16 = !{!"omnipotent char", !17, i64 0} +!17 = !{!"Simple C/C++ TBAA"} +!18 = !DILocation(line: 2, column: 3, scope: !10) diff --git a/llvm/test/CodeGen/Hexagon/misaligned-const-store.ll b/llvm/test/CodeGen/Hexagon/misaligned-const-store.ll new file mode 100644 index 00000000000..b24cd778449 --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/misaligned-const-store.ll @@ -0,0 +1,38 @@ +; RUN: not llc -march=hexagon < %s 2>&1 | FileCheck %s + +; Check that the misaligned store is diagnosed. +; CHECK: LLVM ERROR: Misaligned constant address: 0x00012345 has alignment 1, but the memory access requires 4, at misaligned-const-store.c:2:10 + +target triple = "hexagon" + +define void @bad_store(i32 %a0) #0 !dbg !10 { +entry: + store i32 %a0, i32* inttoptr (i32 74565 to i32*), align 4, !dbg !13, !tbaa !14 + ret void, !dbg !18 +} + +attributes #0 = { norecurse nounwind readonly "target-cpu"="hexagonv60" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 (http://llvm.org/git/clang.git 3fb90d137ea16e5c3a4580b9db5fd18d93df1a90) (http://llvm.org/git/llvm.git daf385e5698c00fdd693fac736acc96b95ccccd3)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3) +!1 = !DIFile(filename: "misaligned-const-store.c", directory: "/test") +!2 = !{} +!3 = !{!4} +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 32) +!5 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!6 = !{i32 2, !"Dwarf Version", i32 4} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i32 1, !"wchar_size", i32 4} +!9 = !{!"clang version 8.0.0 (http://llvm.org/git/clang.git 3fb90d137ea16e5c3a4580b9db5fd18d93df1a90) (http://llvm.org/git/llvm.git daf385e5698c00fdd693fac736acc96b95ccccd3)"} +!10 = distinct !DISubprogram(name: "bad_store", scope: !1, file: !1, line: 1, type: !11, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: true, unit: !0, retainedNodes: !2) +!11 = !DISubroutineType(types: !12) +!12 = !{!5} +!13 = !DILocation(line: 2, column: 10, scope: !10) +!14 = !{!15, !15, i64 0} +!15 = !{!"int", !16, i64 0} +!16 = !{!"omnipotent char", !17, i64 0} +!17 = !{!"Simple C/C++ TBAA"} +!18 = !DILocation(line: 2, column: 3, scope: !10) |

