mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
[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
This commit is contained in:
parent
b83eae9454
commit
39116ea918
@ -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);
|
||||
|
@ -341,8 +341,9 @@ private:
|
||||
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;
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user