Index: lib/Target/Hexagon/HexagonISelLowering.h =================================================================== --- lib/Target/Hexagon/HexagonISelLowering.h +++ lib/Target/Hexagon/HexagonISelLowering.h @@ -317,8 +317,9 @@ private: void initializeHVXLowering(); - void validateConstPtrAlignment(SDValue Ptr, const SDLoc &dl, - unsigned NeedAlign) const; + bool validateConstPtrAlignment(SDValue Ptr, const SDLoc &dl, + unsigned NeedAlign, SelectionDAG &DAG) const; + SDValue replaceMemWithUndef(SDValue Op, SelectionDAG &DAG) const; std::pair getBaseAndOffset(SDValue Addr) const; Index: lib/Target/Hexagon/HexagonISelLowering.cpp =================================================================== --- lib/Target/Hexagon/HexagonISelLowering.cpp +++ lib/Target/Hexagon/HexagonISelLowering.cpp @@ -35,6 +35,8 @@ #include "llvm/IR/CallingConv.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/InlineAsm.h" @@ -1726,24 +1728,66 @@ return nullptr; } -void +bool HexagonTargetLowering::validateConstPtrAlignment(SDValue Ptr, const SDLoc &dl, - unsigned NeedAlign) const { + unsigned NeedAlign, SelectionDAG &DAG) const { auto *CA = dyn_cast(Ptr); if (!CA) - return; + return true; 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()); + if (HaveAlign >= NeedAlign) + return true; + + static int DK_MisalignedTrap = llvm::getNextAvailablePluginDiagnosticKind(); + + struct DiagnosticInfoMisalignedTrap : public DiagnosticInfo { + DiagnosticInfoMisalignedTrap(StringRef M) + : DiagnosticInfo(DK_MisalignedTrap, DS_Remark), Msg(M) {} + void print(DiagnosticPrinter &DP) const override { + DP << Msg; + } + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == DK_MisalignedTrap; + } + StringRef Msg; + }; + + 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 "); + O << ". The instruction has been replaced with a trap."; + + DAG.getContext()->diagnose(DiagnosticInfoMisalignedTrap(O.str())); + return false; +} + +SDValue +HexagonTargetLowering::replaceMemWithUndef(SDValue Op, SelectionDAG &DAG) + const { + const SDLoc &dl(Op); + auto *LS = cast(Op.getNode()); + SDValue Chain = LS->getChain(); + SDValue Addr = LS->getBasePtr(); + SDValue Off = LS->getOffset(); + + SDValue Trap = DAG.getNode(ISD::TRAP, dl, MVT::Other, Chain); + unsigned Opc = LS->getOpcode(); + + if (LS->isIndexed()) { + SDValue Inc = DAG.getNode(ISD::ADD, dl, ty(Addr), Addr, Off); + if (Opc == ISD::LOAD) + return DAG.getMergeValues({DAG.getUNDEF(ty(Op)), Inc, Trap}, dl); + return DAG.getMergeValues({Inc, Trap}, dl); } + + if (Opc == ISD::LOAD) + return DAG.getMergeValues({DAG.getUNDEF(ty(Op)), Trap}, dl); + return Trap; } // Bit-reverse Load Intrinsic: Check if the instruction is a bit reverse load @@ -2654,7 +2698,8 @@ HexagonTargetLowering::LowerLoad(SDValue Op, SelectionDAG &DAG) const { LoadSDNode *LN = cast(Op.getNode()); unsigned ClaimAlign = LN->getAlignment(); - validateConstPtrAlignment(LN->getBasePtr(), SDLoc(Op), ClaimAlign); + if (!validateConstPtrAlignment(LN->getBasePtr(), SDLoc(Op), ClaimAlign, DAG)) + return replaceMemWithUndef(Op, DAG); // Call LowerUnalignedLoad for all loads, it recognizes loads that // don't need extra aligning. return LowerUnalignedLoad(Op, DAG); @@ -2664,9 +2709,8 @@ HexagonTargetLowering::LowerStore(SDValue Op, SelectionDAG &DAG) const { StoreSDNode *SN = cast(Op.getNode()); unsigned ClaimAlign = SN->getAlignment(); - SDValue Ptr = SN->getBasePtr(); - const SDLoc &dl(Op); - validateConstPtrAlignment(Ptr, dl, ClaimAlign); + if (!validateConstPtrAlignment(SN->getBasePtr(), SDLoc(Op), ClaimAlign, DAG)) + return replaceMemWithUndef(Op, DAG); MVT StoreTy = SN->getMemoryVT().getSimpleVT(); unsigned NeedAlign = Subtarget.getTypeAlignment(StoreTy); Index: test/CodeGen/Hexagon/misaligned-const-load.ll =================================================================== --- test/CodeGen/Hexagon/misaligned-const-load.ll +++ test/CodeGen/Hexagon/misaligned-const-load.ll @@ -1,7 +1,7 @@ -; RUN: not llc -march=hexagon < %s 2>&1 | FileCheck %s +; RUN: 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 +; CHECK: remark: Misaligned constant address: 0x00012345 has alignment 1, but the memory access requires 4, at misaligned-const-load.c:2:10. The instruction has been replaced with a trap. target triple = "hexagon" Index: test/CodeGen/Hexagon/misaligned-const-store.ll =================================================================== --- test/CodeGen/Hexagon/misaligned-const-store.ll +++ test/CodeGen/Hexagon/misaligned-const-store.ll @@ -1,7 +1,7 @@ -; RUN: not llc -march=hexagon < %s 2>&1 | FileCheck %s +; RUN: 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 +; CHECK: remark: Misaligned constant address: 0x00012345 has alignment 1, but the memory access requires 4, at misaligned-const-store.c:2:10. The instruction has been replaced with a trap. target triple = "hexagon"