tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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:
Mbuild/build-clang/clang-20.json | 2++
Mbuild/build-clang/clang-21.json | 2++
Abuild/build-clang/llvmorg-22-init-1937-g2672719a09cf.patch | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Abuild/build-clang/llvmorg-22-init-2380-gd9971be83e5d.patch | 150+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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 +