[PATCH] D124780: [SystemZ] Accept (. - 0x100000000) PCRel32 constants

Ilya Leoshkevich via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon May 2 09:42:06 PDT 2022


iii created this revision.
iii added reviewers: uweigand, jonpa.
Herald added a subscriber: hiraditya.
Herald added a project: All.
iii requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D124780

Files:
  llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
  llvm/test/MC/SystemZ/insn-bad.s
  llvm/test/MC/SystemZ/insn-good.s


Index: llvm/test/MC/SystemZ/insn-good.s
===================================================================
--- llvm/test/MC/SystemZ/insn-good.s
+++ 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]
Index: llvm/test/MC/SystemZ/insn-bad.s
===================================================================
--- llvm/test/MC/SystemZ/insn-bad.s
+++ 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
Index: llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
===================================================================
--- llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
+++ llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
@@ -1590,9 +1590,11 @@
   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 @@
       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 @@
   // 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;
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D124780.426436.patch
Type: text/x-patch
Size: 3508 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220502/dac0bee5/attachment.bin>


More information about the llvm-commits mailing list