[llvm] 8d7a17b - [AArch64] Fix the upper limit for folded address offsets for COFF

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 6 12:55:17 PDT 2022


Author: Martin Storsjö
Date: 2022-04-06T22:54:13+03:00
New Revision: 8d7a17b7c8b7151b8453903db96fc7f45d9b1bae

URL: https://github.com/llvm/llvm-project/commit/8d7a17b7c8b7151b8453903db96fc7f45d9b1bae
DIFF: https://github.com/llvm/llvm-project/commit/8d7a17b7c8b7151b8453903db96fc7f45d9b1bae.diff

LOG: [AArch64] Fix the upper limit for folded address offsets for COFF

In COFF, the immediates in IMAGE_REL_ARM64_PAGEBASE_REL21 relocations
are limited to 21 bit signed, i.e. the offset has to be less than
(1 << 20). The previous limit did intend to cover for this case, but
had missed that the 21 bit field was signed.

This fixes issue https://github.com/llvm/llvm-project/issues/54753.

Differential Revision: https://reviews.llvm.org/D123160

Added: 
    

Modified: 
    llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
    llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp
    llvm/test/CodeGen/AArch64/fold-global-offsets.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 80eaa38306577..4f47302bac249 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -17929,13 +17929,14 @@ static SDValue performGlobalAddressCombine(SDNode *N, SelectionDAG &DAG,
 
   // Check whether folding this offset is legal. It must not go out of bounds of
   // the referenced object to avoid violating the code model, and must be
-  // smaller than 2^21 because this is the largest offset expressible in all
-  // object formats.
+  // smaller than 2^20 because this is the largest offset expressible in all
+  // object formats. (The IMAGE_REL_ARM64_PAGEBASE_REL21 relocation in COFF
+  // stores an immediate signed 21 bit offset.)
   //
   // This check also prevents us from folding negative offsets, which will end
   // up being treated in the same way as large positive ones. They could also
   // cause code model violations, and aren't really common enough to matter.
-  if (Offset >= (1 << 21))
+  if (Offset >= (1 << 20))
     return SDValue();
 
   const GlobalValue *GV = GN->getGlobal();

diff  --git a/llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp
index f37eb10ea3e58..275949c5ee642 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp
@@ -163,13 +163,14 @@ static bool matchFoldGlobalOffset(MachineInstr &MI, MachineRegisterInfo &MRI,
 
   // Check whether folding this offset is legal. It must not go out of bounds of
   // the referenced object to avoid violating the code model, and must be
-  // smaller than 2^21 because this is the largest offset expressible in all
-  // object formats.
+  // smaller than 2^20 because this is the largest offset expressible in all
+  // object formats. (The IMAGE_REL_ARM64_PAGEBASE_REL21 relocation in COFF
+  // stores an immediate signed 21 bit offset.)
   //
   // This check also prevents us from folding negative offsets, which will end
   // up being treated in the same way as large positive ones. They could also
   // cause code model violations, and aren't really common enough to matter.
-  if (NewOffset >= (1 << 21))
+  if (NewOffset >= (1 << 20))
     return false;
 
   Type *T = GV->getValueType();

diff  --git a/llvm/test/CodeGen/AArch64/fold-global-offsets.ll b/llvm/test/CodeGen/AArch64/fold-global-offsets.ll
index c57de0d796bda..aa5435c4fd6b3 100644
--- a/llvm/test/CodeGen/AArch64/fold-global-offsets.ll
+++ b/llvm/test/CodeGen/AArch64/fold-global-offsets.ll
@@ -84,23 +84,23 @@ define [2 x i64] @f4() {
 define i64 @f5() {
 ; CHECK-LABEL: f5:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    adrp x8, x2+2097144
-; CHECK-NEXT:    ldr x0, [x8, :lo12:x2+2097144]
+; CHECK-NEXT:    adrp x8, x2+1048568
+; CHECK-NEXT:    ldr x0, [x8, :lo12:x2+1048568]
 ; CHECK-NEXT:    ret
 ;
 ; GISEL-LABEL: f5:
 ; GISEL:       // %bb.0:
-; GISEL-NEXT:    adrp x8, x2+2097144
-; GISEL-NEXT:    ldr x0, [x8, :lo12:x2+2097144]
+; GISEL-NEXT:    adrp x8, x2+1048568
+; GISEL-NEXT:    ldr x0, [x8, :lo12:x2+1048568]
 ; GISEL-NEXT:    ret
-  %l = load i64, i64* getelementptr ([16777216 x i64], [16777216 x i64]* @x2, i64 0, i64 262143)
+  %l = load i64, i64* getelementptr ([16777216 x i64], [16777216 x i64]* @x2, i64 0, i64 131071)
   ret i64 %l
 }
 
 define i64 @f6() {
 ; CHECK-LABEL: f6:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    mov w8, #2097152
+; CHECK-NEXT:    mov w8, #1048576
 ; CHECK-NEXT:    adrp x9, x2
 ; CHECK-NEXT:    add x9, x9, :lo12:x2
 ; CHECK-NEXT:    ldr x0, [x9, x8]
@@ -108,12 +108,12 @@ define i64 @f6() {
 ;
 ; GISEL-LABEL: f6:
 ; GISEL:       // %bb.0:
-; GISEL-NEXT:    mov w8, #2097152
+; GISEL-NEXT:    mov w8, #1048576
 ; GISEL-NEXT:    adrp x9, x2
 ; GISEL-NEXT:    add x9, x9, :lo12:x2
 ; GISEL-NEXT:    ldr x0, [x9, x8]
 ; GISEL-NEXT:    ret
-  %l = load i64, i64* getelementptr ([16777216 x i64], [16777216 x i64]* @x2, i64 0, i64 262144)
+  %l = load i64, i64* getelementptr ([16777216 x i64], [16777216 x i64]* @x2, i64 0, i64 131072)
   ret i64 %l
 }
 


        


More information about the llvm-commits mailing list