[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