[llvm] 734881a - [Hexagon] Fix range checks for immediate operands
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 19 08:22:50 PDT 2023
Author: Krzysztof Parzyszek
Date: 2023-06-19T08:22:41-07:00
New Revision: 734881a6d546c6065a4aa43c3d876337b8b2a263
URL: https://github.com/llvm/llvm-project/commit/734881a6d546c6065a4aa43c3d876337b8b2a263
DIFF: https://github.com/llvm/llvm-project/commit/734881a6d546c6065a4aa43c3d876337b8b2a263.diff
LOG: [Hexagon] Fix range checks for immediate operands
The output assembly (textual) contains the instruction
r29 = add(r29,#4294967136)
The value 4294967136 is -160 when interpreted as a signed 32-bit
integer, so it fits in the range of the immediate operand without
a constant extender. The range check in HexagonInstrInfo was putting
the operand value into an int variable, reporting no need for an
extender. This resulted in a packet with 4 instructions, including
the "add". The corresponding check in HexagonMCInstrInfo was using
an int64_t variable, causing the range check to fail, and an extender
to be emitted when lowering to MCInst, resulting in a packet with
too many instructions.
Added:
llvm/test/CodeGen/Hexagon/imm-range-check.ll
Modified:
llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
index 55ddad2378ac9..15a09195eaca2 100644
--- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
@@ -2177,11 +2177,17 @@ bool HexagonInstrInfo::isConstExtended(const MachineInstr &MI) const {
// have 'isExtended' flag set.
assert(MO.isImm() && "Extendable operand must be Immediate type");
- int MinValue = getMinValue(MI);
- int MaxValue = getMaxValue(MI);
- int ImmValue = MO.getImm();
-
- return (ImmValue < MinValue || ImmValue > MaxValue);
+ int64_t Value = MO.getImm();
+ if ((F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask) {
+ int32_t SValue = Value;
+ int32_t MinValue = getMinValue(MI);
+ int32_t MaxValue = getMaxValue(MI);
+ return SValue < MinValue || SValue > MaxValue;
+ }
+ uint32_t UValue = Value;
+ uint32_t MinValue = getMinValue(MI);
+ uint32_t MaxValue = getMaxValue(MI);
+ return UValue < MinValue || UValue > MaxValue;
}
bool HexagonInstrInfo::isDeallocRet(const MachineInstr &MI) const {
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
index 0fd002ac56909..9cf004cf4c9a5 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
@@ -568,12 +568,20 @@ bool HexagonMCInstrInfo::isConstExtended(MCInstrInfo const &MCII,
if (isa<HexagonMCExpr>(MO.getExpr()) &&
HexagonMCInstrInfo::mustNotExtend(*MO.getExpr()))
return false;
+
int64_t Value;
if (!MO.getExpr()->evaluateAsAbsolute(Value))
return true;
- int MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI);
- int MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI);
- return (MinValue > Value || Value > MaxValue);
+ if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) {
+ int32_t SValue = Value;
+ int32_t MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI);
+ int32_t MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI);
+ return SValue < MinValue || SValue > MaxValue;
+ }
+ uint32_t UValue = Value;
+ uint32_t MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI);
+ uint32_t MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI);
+ return UValue < MinValue || UValue > MaxValue;
}
bool HexagonMCInstrInfo::isCanon(MCInstrInfo const &MCII, MCInst const &MCI) {
diff --git a/llvm/test/CodeGen/Hexagon/imm-range-check.ll b/llvm/test/CodeGen/Hexagon/imm-range-check.ll
new file mode 100644
index 0000000000000..290a5b69d3334
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/imm-range-check.ll
@@ -0,0 +1,26 @@
+; RUN: llc -march=hexagon -filetype=obj < %s | llvm-objdump -d - | FileCheck %s
+
+; The output assembly (textual) contains the instruction
+; r29 = add(r29,#4294967136)
+; The value 4294967136 is -160 when interpreted as a signed 32-bit
+; integer, so it fits in the range of the immediate operand without
+; a constant extender. The range check in HexagonInstrInfo was putting
+; the operand value into an int variable, reporting no need for an
+; extender. This resulted in a packet with 4 instructions, including
+; the "add". The corresponding check in HexagonMCInstrInfo was using
+; an int64_t variable, causing an extender to be emitted when lowering
+; to MCInst, and resulting in a packet with 5 instructions.
+
+; Check that this doesn't crash.
+; CHECK: r29 = add(r29,#-0xa0)
+
+target triple = "hexagon-unknown-linux-gnu"
+
+define float @f0() {
+b0:
+ %v0 = alloca i8, i32 0, align 1
+ %v1 = alloca float, i32 -42, align 4
+ %v2 = load float, ptr %v1, align 4
+ store i8 0, ptr %v0, align 1
+ ret float %v2
+}
More information about the llvm-commits
mailing list