diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h @@ -341,8 +341,9 @@ void initializeHVXLowering(); unsigned getPreferredHvxVectorAction(MVT VecTy) const; - void validateConstPtrAlignment(SDValue Ptr, Align NeedAlign, - const SDLoc &dl) const; + bool validateConstPtrAlignment(SDValue Ptr, Align NeedAlign, const SDLoc &dl, + SelectionDAG &DAG) const; + SDValue replaceMemWithUndef(SDValue Op, SelectionDAG &DAG) const; std::pair getBaseAndOffset(SDValue Addr) const; diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/llvm/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" @@ -1912,25 +1914,57 @@ return nullptr; } -void +bool HexagonTargetLowering::validateConstPtrAlignment(SDValue Ptr, Align NeedAlign, - const SDLoc &dl) const { + const SDLoc &dl, SelectionDAG &DAG) const { auto *CA = dyn_cast(Ptr); if (!CA) - return; + return true; unsigned Addr = CA->getZExtValue(); Align HaveAlign = Addr != 0 ? Align(1ull << 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.value() - << ", but the memory access requires " << NeedAlign.value(); - 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.value() + << ", but the memory access requires " << NeedAlign.value(); + 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()); + assert(!LS->isIndexed() && "Not expecting indexed ops on constant address"); + + SDValue Chain = LS->getChain(); + SDValue Trap = DAG.getNode(ISD::TRAP, dl, MVT::Other, Chain); + if (LS->getOpcode() == 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 @@ -2902,7 +2936,9 @@ } Align ClaimAlign = LN->getAlign(); - validateConstPtrAlignment(LN->getBasePtr(), ClaimAlign, dl); + if (!validateConstPtrAlignment(LN->getBasePtr(), ClaimAlign, dl, DAG)) + return replaceMemWithUndef(Op, DAG); + // Call LowerUnalignedLoad for all loads, it recognizes loads that // don't need extra aligning. SDValue LU = LowerUnalignedLoad(SDValue(LN, 0), DAG); @@ -2934,7 +2970,8 @@ } Align ClaimAlign = SN->getAlign(); - validateConstPtrAlignment(SN->getBasePtr(), ClaimAlign, dl); + if (!validateConstPtrAlignment(SN->getBasePtr(), ClaimAlign, dl, DAG)) + return replaceMemWithUndef(Op, DAG); MVT StoreTy = SN->getMemoryVT().getSimpleVT(); Align NeedAlign = Subtarget.getTypeAlignment(StoreTy); diff --git a/llvm/test/CodeGen/Hexagon/misaligned-const-load.ll b/llvm/test/CodeGen/Hexagon/misaligned-const-load.ll --- a/llvm/test/CodeGen/Hexagon/misaligned-const-load.ll +++ b/llvm/test/CodeGen/Hexagon/misaligned-const-load.ll @@ -1,7 +1,7 @@ -; RUN: not --crash 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" diff --git a/llvm/test/CodeGen/Hexagon/misaligned-const-store.ll b/llvm/test/CodeGen/Hexagon/misaligned-const-store.ll --- a/llvm/test/CodeGen/Hexagon/misaligned-const-store.ll +++ b/llvm/test/CodeGen/Hexagon/misaligned-const-store.ll @@ -1,7 +1,7 @@ -; RUN: not --crash 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"