commit b4ea0dcb568f15165133a9a49ea8e6e7e114fd37
parent 617d3747f1fa562c0f4d2b68bb3e9882f652a306
Author: serge-sans-paille <sguelton@mozilla.com>
Date: Wed, 10 Dec 2025 10:30:34 +0000
Bug 2003320 - Backport upstream LLVM patches that fix glean compilation error to clang-2[01] r=yjuglaret,firefox-build-system-reviewers,glandium
Cherry-picked from the main branch, patch not present in llvmorg-21.1.7 branch.
Differential Revision: https://phabricator.services.mozilla.com/D275224
Diffstat:
4 files changed, 204 insertions(+), 0 deletions(-)
diff --git a/build/build-clang/clang-20.json b/build/build-clang/clang-20.json
@@ -10,6 +10,8 @@
"revert-llvmorg-15-init-13446-g7524fe962e47.patch",
"llvmorg-21-init-2651-gbac417107339.patch",
"llvmorg-21-init-17702-g0d7e64f5d2b4.patch",
+ "llvmorg-22-init-1937-g2672719a09cf.patch",
+ "llvmorg-22-init-2380-gd9971be83e5d.patch",
"llvmorg-22-init-4745-gbe179d069664.patch",
"llvmorg-22-init-11861-gfbcd82aab5ff.patch",
"android-hardware-buffer-header-workaround.patch",
diff --git a/build/build-clang/clang-21.json b/build/build-clang/clang-21.json
@@ -8,6 +8,8 @@
"fuzzing_ccov_build_clang_12.patch",
"revert-llvmorg-16-init-11301-g163bb6d64e5f_clang_21.patch",
"revert-llvmorg-15-init-13446-g7524fe962e47.patch",
+ "llvmorg-22-init-1937-g2672719a09cf.patch",
+ "llvmorg-22-init-2380-gd9971be83e5d.patch",
"llvmorg-22-init-4745-gbe179d069664.patch",
"llvmorg-22-init-11861-gfbcd82aab5ff.patch",
"android-hardware-buffer-header-workaround_clang_21.patch",
diff --git a/build/build-clang/llvmorg-22-init-1937-g2672719a09cf.patch b/build/build-clang/llvmorg-22-init-1937-g2672719a09cf.patch
@@ -0,0 +1,50 @@
+From ce610275edfd05704d5058716a971c2003299b95 Mon Sep 17 00:00:00 2001
+From: Nikita Popov <npopov@redhat.com>
+Date: Wed, 30 Jul 2025 17:52:08 +0200
+Subject: [PATCH 1/2] [InstCombine] Don't handle non-canonical index type in
+ icmp of load fold (#151346)
+
+We should just bail out and wait for it to be canonicalized. The current
+implementation could emit a trunc without actually performing the
+transform.
+---
+ .../InstCombine/InstCombineCompares.cpp | 16 +++++-----------
+ 1 file changed, 5 insertions(+), 11 deletions(-)
+
+diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+index 810ce7d382ae..19dd71355622 100644
+--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
++++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+@@ -161,6 +161,11 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
+ LaterIndices.push_back(IdxVal);
+ }
+
++ Value *Idx = GEP->getOperand(2);
++ // If the index type is non-canonical, wait for it to be canonicalized.
++ if (Idx->getType() != DL.getIndexType(GEP->getType()))
++ return nullptr;
++
+ enum { Overdefined = -3, Undefined = -2 };
+
+ // Variables for our state machines.
+@@ -288,17 +293,6 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
+
+ // Now that we've scanned the entire array, emit our new comparison(s). We
+ // order the state machines in complexity of the generated code.
+- Value *Idx = GEP->getOperand(2);
+-
+- // If the index is larger than the pointer offset size of the target, truncate
+- // the index down like the GEP would do implicitly. We don't have to do this
+- // for an inbounds GEP because the index can't be out of range.
+- if (!GEP->isInBounds()) {
+- Type *PtrIdxTy = DL.getIndexType(GEP->getType());
+- unsigned OffsetSize = PtrIdxTy->getIntegerBitWidth();
+- if (Idx->getType()->getPrimitiveSizeInBits().getFixedValue() > OffsetSize)
+- Idx = Builder.CreateTrunc(Idx, PtrIdxTy);
+- }
+
+ // If inbounds keyword is not present, Idx * ElementSize can overflow.
+ // Let's assume that ElementSize is 2 and the wanted value is at offset 0.
+--
+2.51.0
+
diff --git a/build/build-clang/llvmorg-22-init-2380-gd9971be83e5d.patch b/build/build-clang/llvmorg-22-init-2380-gd9971be83e5d.patch
@@ -0,0 +1,150 @@
+From 4d453e70c33e5262531e64bf01278a6b9e4085fb Mon Sep 17 00:00:00 2001
+From: David Green <david.green@arm.com>
+Date: Sun, 3 Aug 2025 10:19:42 +0100
+Subject: [PATCH 2/2] [InstCombine] Make foldCmpLoadFromIndexedGlobal more
+ resilient to non-array geps. (#150639)
+
+My understanding is that gep [n x i8] and gep i8 can be treated
+equivalently - the array type conveys no extra information and could be
+removed. This goes through foldCmpLoadFromIndexedGlobal and tries to
+make it work for non-array gep types, so long as the index type still
+matches the array being loaded.
+---
+ .../InstCombine/InstCombineCompares.cpp | 29 ++++++++++++-----
+ llvm/test/Transforms/InstCombine/load-cmp.ll | 32 ++++++++++++++++++-
+ 2 files changed, 52 insertions(+), 9 deletions(-)
+
+diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+index 19dd71355622..3d49c60d1648 100644
+--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
++++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+@@ -111,10 +111,16 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
+ LoadInst *LI, GetElementPtrInst *GEP, GlobalVariable *GV, CmpInst &ICI,
+ ConstantInt *AndCst) {
+ if (LI->isVolatile() || LI->getType() != GEP->getResultElementType() ||
+- GV->getValueType() != GEP->getSourceElementType() || !GV->isConstant() ||
++ !GV->getValueType()->isArrayTy() || !GV->isConstant() ||
+ !GV->hasDefinitiveInitializer())
+ return nullptr;
+
++ Type *GEPSrcEltTy = GEP->getSourceElementType();
++ if (GEPSrcEltTy->isArrayTy())
++ GEPSrcEltTy = GEPSrcEltTy->getArrayElementType();
++ if (GV->getValueType()->getArrayElementType() != GEPSrcEltTy)
++ return nullptr;
++
+ Constant *Init = GV->getInitializer();
+ if (!isa<ConstantArray>(Init) && !isa<ConstantDataArray>(Init))
+ return nullptr;
+@@ -125,12 +131,19 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
+ return nullptr;
+
+ // There are many forms of this optimization we can handle, for now, just do
+- // the simple index into a single-dimensional array.
++ // the simple index into a single-dimensional array or elements of equal size.
+ //
+- // Require: GEP GV, 0, i {{, constant indices}}
+- if (GEP->getNumOperands() < 3 || !isa<ConstantInt>(GEP->getOperand(1)) ||
+- !cast<ConstantInt>(GEP->getOperand(1))->isZero() ||
+- isa<Constant>(GEP->getOperand(2)))
++ // Require: GEP [n x i8] GV, 0, Idx {{, constant indices}}
++ // Or: GEP i8 GV, Idx
++
++ unsigned GEPIdxOp = 1;
++ if (GEP->getSourceElementType()->isArrayTy()) {
++ GEPIdxOp = 2;
++ if (!match(GEP->getOperand(1), m_ZeroInt()))
++ return nullptr;
++ }
++ if (GEP->getNumOperands() < GEPIdxOp + 1 ||
++ isa<Constant>(GEP->getOperand(GEPIdxOp)))
+ return nullptr;
+
+ // Check that indices after the variable are constants and in-range for the
+@@ -139,7 +152,7 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
+ SmallVector<unsigned, 4> LaterIndices;
+
+ Type *EltTy = Init->getType()->getArrayElementType();
+- for (unsigned i = 3, e = GEP->getNumOperands(); i != e; ++i) {
++ for (unsigned i = GEPIdxOp + 1, e = GEP->getNumOperands(); i != e; ++i) {
+ ConstantInt *Idx = dyn_cast<ConstantInt>(GEP->getOperand(i));
+ if (!Idx)
+ return nullptr; // Variable index.
+@@ -161,7 +174,7 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
+ LaterIndices.push_back(IdxVal);
+ }
+
+- Value *Idx = GEP->getOperand(2);
++ Value *Idx = GEP->getOperand(GEPIdxOp);
+ // If the index type is non-canonical, wait for it to be canonicalized.
+ if (Idx->getType() != DL.getIndexType(GEP->getType()))
+ return nullptr;
+diff --git a/llvm/test/Transforms/InstCombine/load-cmp.ll b/llvm/test/Transforms/InstCombine/load-cmp.ll
+index 12be81b8f815..485da6d2aaec 100644
+--- a/llvm/test/Transforms/InstCombine/load-cmp.ll
++++ b/llvm/test/Transforms/InstCombine/load-cmp.ll
+@@ -68,7 +68,6 @@ define i1 @test1_noinbounds_as1(i32 %x) {
+ %q = load i16, ptr addrspace(1) %p
+ %r = icmp eq i16 %q, 0
+ ret i1 %r
+-
+ }
+
+ define i1 @test1_noinbounds_as2(i64 %x) {
+@@ -81,7 +80,17 @@ define i1 @test1_noinbounds_as2(i64 %x) {
+ %q = load i16, ptr addrspace(2) %p
+ %r = icmp eq i16 %q, 0
+ ret i1 %r
++}
+
++define i1 @test1_noarrayty(i32 %X) {
++; CHECK-LABEL: @test1_noarrayty(
++; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X:%.*]], 9
++; CHECK-NEXT: ret i1 [[R]]
++;
++ %P = getelementptr inbounds i16, ptr @G16, i32 %X
++ %Q = load i16, ptr %P
++ %R = icmp eq i16 %Q, 0
++ ret i1 %R
+ }
+
+ define i1 @test2(i32 %X) {
+@@ -104,7 +113,17 @@ define i1 @test3(i32 %X) {
+ %Q = load double, ptr %P
+ %R = fcmp oeq double %Q, 1.0
+ ret i1 %R
++}
+
++define i1 @test3_noarrayty(i32 %X) {
++; CHECK-LABEL: @test3_noarrayty(
++; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X:%.*]], 1
++; CHECK-NEXT: ret i1 [[R]]
++;
++ %P = getelementptr inbounds double, ptr @GD, i32 %X
++ %Q = load double, ptr %P
++ %R = fcmp oeq double %Q, 1.0
++ ret i1 %R
+ }
+
+ define i1 @test4(i32 %X) {
+@@ -333,6 +352,17 @@ define i1 @test10_struct_arr_noinbounds_i64(i64 %x) {
+ ret i1 %r
+ }
+
++define i1 @test10_struct_arr_noarrayty(i32 %x) {
++; CHECK-LABEL: @test10_struct_arr_noarrayty(
++; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[X:%.*]], 1
++; CHECK-NEXT: ret i1 [[R]]
++;
++ %p = getelementptr inbounds %Foo, ptr @GStructArr, i32 %x, i32 2
++ %q = load i32, ptr %p
++ %r = icmp eq i32 %q, 9
++ ret i1 %r
++}
++
+ @table = internal constant [2 x ptr] [ptr @g, ptr getelementptr (i8, ptr @g, i64 4)], align 16
+ @g = external global [2 x i32]
+
+--
+2.51.0
+