[llvm] 94e01d5 - [Hexagon] Generate trap/undef if misaligned access is detected
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 6 13:21:00 PDT 2021
Author: Krzysztof Parzyszek
Date: 2021-07-06T14:52:23-05:00
New Revision: 94e01d579c1954bed2dbd2d82a64ff72baf72223
URL: https://github.com/llvm/llvm-project/commit/94e01d579c1954bed2dbd2d82a64ff72baf72223
DIFF: https://github.com/llvm/llvm-project/commit/94e01d579c1954bed2dbd2d82a64ff72baf72223.diff
LOG: [Hexagon] Generate trap/undef if misaligned access is detected
This applies to memory accesses to (compile-time) constant addresses
(such as memory-mapped registers). Currently when a misaligned access
to such an address is detected, a fatal error is reported. This change
will emit a remark, and the compilation will continue with a trap,
and "undef" (for loads) emitted.
This fixes https://llvm.org/PR50838.
Differential Revision: https://reviews.llvm.org/D50524
Added:
Modified:
llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
llvm/lib/Target/Hexagon/HexagonISelLowering.h
llvm/test/CodeGen/Hexagon/misaligned-const-load.ll
llvm/test/CodeGen/Hexagon/misaligned-const-store.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
index 06fee76c4ffe9..6ded323a34c30 100644
--- 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 @@ const char* HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const {
return nullptr;
}
-void
+bool
HexagonTargetLowering::validateConstPtrAlignment(SDValue Ptr, Align NeedAlign,
- const SDLoc &dl) const {
+ const SDLoc &dl, SelectionDAG &DAG) const {
auto *CA = dyn_cast<ConstantSDNode>(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<LSBaseSDNode>(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 @@ HexagonTargetLowering::LowerLoad(SDValue Op, SelectionDAG &DAG) const {
}
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 @@ HexagonTargetLowering::LowerStore(SDValue Op, SelectionDAG &DAG) const {
}
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/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
index 7d376f9f86a04..d518c036f1250 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
@@ -341,8 +341,9 @@ class HexagonTargetLowering : public TargetLowering {
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<SDValue,int> getBaseAndOffset(SDValue Addr) const;
diff --git a/llvm/test/CodeGen/Hexagon/misaligned-const-load.ll b/llvm/test/CodeGen/Hexagon/misaligned-const-load.ll
index 74b744305a075..f209d80eed3b5 100644
--- 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
index 0a5b1aafcc01b..27f472ef0c909 100644
--- 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"
More information about the llvm-commits
mailing list