diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -17929,13 +17929,14 @@ // 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 --- a/llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp @@ -163,13 +163,14 @@ // 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 --- a/llvm/test/CodeGen/AArch64/fold-global-offsets.ll +++ b/llvm/test/CodeGen/AArch64/fold-global-offsets.ll @@ -84,23 +84,23 @@ 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 @@ ; ; 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 }