[llvm] 7070c6a - [SystemZ] Accept (. - 0x100000000) PCRel32 constants
Eli Shokin via llvm-commits
llvm-commits at lists.llvm.org
Mon May 2 11:58:09 PDT 2022
Author: Ilya Leoshkevich
Date: 2022-05-02T20:57:55+02:00
New Revision: 7070c6a96b418874ac201c6e0ff2070c5c9669d3
URL: https://github.com/llvm/llvm-project/commit/7070c6a96b418874ac201c6e0ff2070c5c9669d3
DIFF: https://github.com/llvm/llvm-project/commit/7070c6a96b418874ac201c6e0ff2070c5c9669d3.diff
LOG: [SystemZ] Accept (. - 0x100000000) PCRel32 constants
Clang does not accept instructions like brasl %r0,.-0x100000000,
because the second operand's right-hand-side (0x100000000) barely
misses the acceptable range. However, since it's being subtracted, it
makes sense to perform the range check on the negated value.
Reviewed By: uweigand
Differential Revision: https://reviews.llvm.org/D124780
Added:
Modified:
llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
llvm/test/MC/SystemZ/insn-bad.s
llvm/test/MC/SystemZ/insn-good.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
index 4f37acc0d398d..60e1b05a6d1ab 100644
--- a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
+++ b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
@@ -1590,9 +1590,11 @@ SystemZAsmParser::parsePCRel(OperandVector &Operands, int64_t MinVal,
if (getParser().parseExpression(Expr))
return MatchOperand_NoMatch;
- auto isOutOfRangeConstant = [&](const MCExpr *E) -> bool {
+ auto isOutOfRangeConstant = [&](const MCExpr *E, bool Negate) -> bool {
if (auto *CE = dyn_cast<MCConstantExpr>(E)) {
int64_t Value = CE->getValue();
+ if (Negate)
+ Value = -Value;
if ((Value & 1) || Value < MinVal || Value > MaxVal)
return true;
}
@@ -1606,7 +1608,7 @@ SystemZAsmParser::parsePCRel(OperandVector &Operands, int64_t MinVal,
Error(StartLoc, "Expected PC-relative expression");
return MatchOperand_ParseFail;
}
- if (isOutOfRangeConstant(CE)) {
+ if (isOutOfRangeConstant(CE, false)) {
Error(StartLoc, "offset out of range");
return MatchOperand_ParseFail;
}
@@ -1621,8 +1623,9 @@ SystemZAsmParser::parsePCRel(OperandVector &Operands, int64_t MinVal,
// For consistency with the GNU assembler, conservatively assume that a
// constant offset must by itself be within the given size range.
if (const auto *BE = dyn_cast<MCBinaryExpr>(Expr))
- if (isOutOfRangeConstant(BE->getLHS()) ||
- isOutOfRangeConstant(BE->getRHS())) {
+ if (isOutOfRangeConstant(BE->getLHS(), false) ||
+ isOutOfRangeConstant(BE->getRHS(),
+ BE->getOpcode() == MCBinaryExpr::Sub)) {
Error(StartLoc, "offset out of range");
return MatchOperand_ParseFail;
}
diff --git a/llvm/test/MC/SystemZ/insn-bad.s b/llvm/test/MC/SystemZ/insn-bad.s
index dbe5b71d92dd3..e6160260ddd1d 100644
--- a/llvm/test/MC/SystemZ/insn-bad.s
+++ b/llvm/test/MC/SystemZ/insn-bad.s
@@ -512,6 +512,8 @@
#CHECK: error: offset out of range
#CHECK: brasl %r0, -0x1000000002
#CHECK: error: offset out of range
+#CHECK: brasl %r0, .-0x1000000002
+#CHECK: error: offset out of range
#CHECK: brasl %r0, -1
#CHECK: error: offset out of range
#CHECK: brasl %r0, 1
@@ -520,6 +522,8 @@
#CHECK: error: offset out of range
#CHECK: jasl %r0, -0x1000000002
#CHECK: error: offset out of range
+#CHECK: jasl %r0, .-0x1000000002
+#CHECK: error: offset out of range
#CHECK: jasl %r0, -1
#CHECK: error: offset out of range
#CHECK: jasl %r0, 1
@@ -527,10 +531,12 @@
#CHECK: jasl %r0, 0x100000000
brasl %r0, -0x1000000002
+ brasl %r0, .-0x1000000002
brasl %r0, -1
brasl %r0, 1
brasl %r0, 0x100000000
jasl %r0, -0x1000000002
+ jasl %r0, .-0x1000000002
jasl %r0, -1
jasl %r0, 1
jasl %r0, 0x100000000
diff --git a/llvm/test/MC/SystemZ/insn-good.s b/llvm/test/MC/SystemZ/insn-good.s
index ce610b529f8e6..e7f73c72880f8 100644
--- a/llvm/test/MC/SystemZ/insn-good.s
+++ b/llvm/test/MC/SystemZ/insn-good.s
@@ -1263,6 +1263,12 @@
#CHECK: fixup A - offset: 2, value: (.[[LAB]]-4294967296)+2, kind: FK_390_PC32DBL
brasl %r0, -0x100000000
jasl %r0, -0x100000000
+#CHECK: brasl %r0, .[[LAB:L.*]]-4294967296 # encoding: [0xc0,0x05,A,A,A,A]
+#CHECK: fixup A - offset: 2, value: (.[[LAB]]-4294967296)+2, kind: FK_390_PC32DBL
+#CHECK: brasl %r0, .[[LAB:L.*]]-4294967296 # encoding: [0xc0,0x05,A,A,A,A]
+#CHECK: fixup A - offset: 2, value: (.[[LAB]]-4294967296)+2, kind: FK_390_PC32DBL
+ brasl %r0, .-0x100000000
+ jasl %r0, .-0x100000000
#CHECK: brasl %r0, .[[LAB:L.*]]-2 # encoding: [0xc0,0x05,A,A,A,A]
#CHECK: fixup A - offset: 2, value: (.[[LAB]]-2)+2, kind: FK_390_PC32DBL
#CHECK: brasl %r0, .[[LAB:L.*]]-2 # encoding: [0xc0,0x05,A,A,A,A]
More information about the llvm-commits
mailing list