diff --git a/llvm/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp b/llvm/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp index 10a46f100bbea..bd9d2de58c8b2 100644 --- a/llvm/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp +++ b/llvm/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp @@ -14,6 +14,7 @@ #include "MCTargetDesc/BPFMCTargetDesc.h" #include "llvm/ADT/SmallVector.h" #include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixup.h" #include "llvm/MC/MCInst.h" @@ -33,11 +34,12 @@ namespace { class BPFMCCodeEmitter : public MCCodeEmitter { const MCRegisterInfo &MRI; bool IsLittleEndian; + MCContext &Ctx; public: BPFMCCodeEmitter(const MCInstrInfo &, const MCRegisterInfo &mri, - bool IsLittleEndian) - : MRI(mri), IsLittleEndian(IsLittleEndian) { } + bool IsLittleEndian, MCContext &ctx) + : MRI(mri), IsLittleEndian(IsLittleEndian), Ctx(ctx) {} BPFMCCodeEmitter(const BPFMCCodeEmitter &) = delete; void operator=(const BPFMCCodeEmitter &) = delete; ~BPFMCCodeEmitter() override = default; @@ -67,12 +69,12 @@ class BPFMCCodeEmitter : public MCCodeEmitter { MCCodeEmitter *llvm::createBPFMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx) { - return new BPFMCCodeEmitter(MCII, *Ctx.getRegisterInfo(), true); + return new BPFMCCodeEmitter(MCII, *Ctx.getRegisterInfo(), true, Ctx); } MCCodeEmitter *llvm::createBPFbeMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx) { - return new BPFMCCodeEmitter(MCII, *Ctx.getRegisterInfo(), false); + return new BPFMCCodeEmitter(MCII, *Ctx.getRegisterInfo(), false, Ctx); } unsigned BPFMCCodeEmitter::getMachineOpValue(const MCInst &MI, @@ -81,8 +83,16 @@ unsigned BPFMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCSubtargetInfo &STI) const { if (MO.isReg()) return MRI.getEncodingValue(MO.getReg()); - if (MO.isImm()) - return static_cast(MO.getImm()); + if (MO.isImm()) { + uint64_t Imm = MO.getImm(); + uint64_t High32Bits = Imm >> 32, High33Bits = Imm >> 31; + if (MI.getOpcode() != BPF::LD_imm64 && High32Bits != 0 && + High33Bits != 0x1FFFFFFFFULL) { + Ctx.reportWarning(MI.getLoc(), + "immediate out of range, shall fit in 32 bits"); + } + return static_cast(Imm); + } assert(MO.isExpr()); diff --git a/llvm/test/CodeGen/BPF/warn-cmp.ll b/llvm/test/CodeGen/BPF/warn-cmp.ll new file mode 100644 index 0000000000000..109d177b0fb42 --- /dev/null +++ b/llvm/test/CodeGen/BPF/warn-cmp.ll @@ -0,0 +1,15 @@ +; RUN: llc -mtriple=bpfel -filetype=obj < %s 2>&1 >/dev/null | FileCheck %s + +; CHECK: warning: immediate out of range, shall fit in 32 bits +define dso_local void @test_1() naked { + tail call void asm sideeffect + "r1 = 40; if r1 == 0x1deadbeef goto +0; r0 = 0; exit;", "~{r0},~{r1}"() + unreachable +} + +; CHECK: warning: immediate out of range, shall fit in 32 bits +define dso_local void @test_2() naked { + tail call void asm sideeffect + "r1 = 40; if r1 == 0xffffffff00000000 goto +0; r0 = 0; exit;", "~{r0},~{r1}"() + unreachable +}