tor-browser

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

llvmorg-22-init-2380-gd9971be83e5d.patch (5613B)


      1 From 4d453e70c33e5262531e64bf01278a6b9e4085fb Mon Sep 17 00:00:00 2001
      2 From: David Green <david.green@arm.com>
      3 Date: Sun, 3 Aug 2025 10:19:42 +0100
      4 Subject: [PATCH 2/2] [InstCombine] Make foldCmpLoadFromIndexedGlobal more
      5 resilient to non-array geps. (#150639)
      6 
      7 My understanding is that gep [n x i8] and gep i8 can be treated
      8 equivalently - the array type conveys no extra information and could be
      9 removed. This goes through foldCmpLoadFromIndexedGlobal and tries to
     10 make it work for non-array gep types, so long as the index type still
     11 matches the array being loaded.
     12 ---
     13 .../InstCombine/InstCombineCompares.cpp       | 29 ++++++++++++-----
     14 llvm/test/Transforms/InstCombine/load-cmp.ll  | 32 ++++++++++++++++++-
     15 2 files changed, 52 insertions(+), 9 deletions(-)
     16 
     17 diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
     18 index 19dd71355622..3d49c60d1648 100644
     19 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
     20 +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
     21 @@ -111,10 +111,16 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
     22     LoadInst *LI, GetElementPtrInst *GEP, GlobalVariable *GV, CmpInst &ICI,
     23     ConstantInt *AndCst) {
     24   if (LI->isVolatile() || LI->getType() != GEP->getResultElementType() ||
     25 -      GV->getValueType() != GEP->getSourceElementType() || !GV->isConstant() ||
     26 +      !GV->getValueType()->isArrayTy() || !GV->isConstant() ||
     27       !GV->hasDefinitiveInitializer())
     28     return nullptr;
     29 
     30 +  Type *GEPSrcEltTy = GEP->getSourceElementType();
     31 +  if (GEPSrcEltTy->isArrayTy())
     32 +    GEPSrcEltTy = GEPSrcEltTy->getArrayElementType();
     33 +  if (GV->getValueType()->getArrayElementType() != GEPSrcEltTy)
     34 +    return nullptr;
     35 +
     36   Constant *Init = GV->getInitializer();
     37   if (!isa<ConstantArray>(Init) && !isa<ConstantDataArray>(Init))
     38     return nullptr;
     39 @@ -125,12 +131,19 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
     40     return nullptr;
     41 
     42   // There are many forms of this optimization we can handle, for now, just do
     43 -  // the simple index into a single-dimensional array.
     44 +  // the simple index into a single-dimensional array or elements of equal size.
     45   //
     46 -  // Require: GEP GV, 0, i {{, constant indices}}
     47 -  if (GEP->getNumOperands() < 3 || !isa<ConstantInt>(GEP->getOperand(1)) ||
     48 -      !cast<ConstantInt>(GEP->getOperand(1))->isZero() ||
     49 -      isa<Constant>(GEP->getOperand(2)))
     50 +  // Require: GEP [n x i8] GV, 0, Idx {{, constant indices}}
     51 +  //      Or: GEP i8 GV, Idx
     52 +
     53 +  unsigned GEPIdxOp = 1;
     54 +  if (GEP->getSourceElementType()->isArrayTy()) {
     55 +    GEPIdxOp = 2;
     56 +    if (!match(GEP->getOperand(1), m_ZeroInt()))
     57 +      return nullptr;
     58 +  }
     59 +  if (GEP->getNumOperands() < GEPIdxOp + 1 ||
     60 +      isa<Constant>(GEP->getOperand(GEPIdxOp)))
     61     return nullptr;
     62 
     63   // Check that indices after the variable are constants and in-range for the
     64 @@ -139,7 +152,7 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
     65   SmallVector<unsigned, 4> LaterIndices;
     66 
     67   Type *EltTy = Init->getType()->getArrayElementType();
     68 -  for (unsigned i = 3, e = GEP->getNumOperands(); i != e; ++i) {
     69 +  for (unsigned i = GEPIdxOp + 1, e = GEP->getNumOperands(); i != e; ++i) {
     70     ConstantInt *Idx = dyn_cast<ConstantInt>(GEP->getOperand(i));
     71     if (!Idx)
     72       return nullptr; // Variable index.
     73 @@ -161,7 +174,7 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
     74     LaterIndices.push_back(IdxVal);
     75   }
     76 
     77 -  Value *Idx = GEP->getOperand(2);
     78 +  Value *Idx = GEP->getOperand(GEPIdxOp);
     79   // If the index type is non-canonical, wait for it to be canonicalized.
     80   if (Idx->getType() != DL.getIndexType(GEP->getType()))
     81     return nullptr;
     82 diff --git a/llvm/test/Transforms/InstCombine/load-cmp.ll b/llvm/test/Transforms/InstCombine/load-cmp.ll
     83 index 12be81b8f815..485da6d2aaec 100644
     84 --- a/llvm/test/Transforms/InstCombine/load-cmp.ll
     85 +++ b/llvm/test/Transforms/InstCombine/load-cmp.ll
     86 @@ -68,7 +68,6 @@ define i1 @test1_noinbounds_as1(i32 %x) {
     87   %q = load i16, ptr addrspace(1) %p
     88   %r = icmp eq i16 %q, 0
     89   ret i1 %r
     90 -
     91 }
     92 
     93 define i1 @test1_noinbounds_as2(i64 %x) {
     94 @@ -81,7 +80,17 @@ define i1 @test1_noinbounds_as2(i64 %x) {
     95   %q = load i16, ptr addrspace(2) %p
     96   %r = icmp eq i16 %q, 0
     97   ret i1 %r
     98 +}
     99 
    100 +define i1 @test1_noarrayty(i32 %X) {
    101 +; CHECK-LABEL: @test1_noarrayty(
    102 +; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[X:%.*]], 9
    103 +; CHECK-NEXT:    ret i1 [[R]]
    104 +;
    105 +  %P = getelementptr inbounds i16, ptr @G16, i32 %X
    106 +  %Q = load i16, ptr %P
    107 +  %R = icmp eq i16 %Q, 0
    108 +  ret i1 %R
    109 }
    110 
    111 define i1 @test2(i32 %X) {
    112 @@ -104,7 +113,17 @@ define i1 @test3(i32 %X) {
    113   %Q = load double, ptr %P
    114   %R = fcmp oeq double %Q, 1.0
    115   ret i1 %R
    116 +}
    117 
    118 +define i1 @test3_noarrayty(i32 %X) {
    119 +; CHECK-LABEL: @test3_noarrayty(
    120 +; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[X:%.*]], 1
    121 +; CHECK-NEXT:    ret i1 [[R]]
    122 +;
    123 +  %P = getelementptr inbounds double, ptr @GD, i32 %X
    124 +  %Q = load double, ptr %P
    125 +  %R = fcmp oeq double %Q, 1.0
    126 +  ret i1 %R
    127 }
    128 
    129 define i1 @test4(i32 %X) {
    130 @@ -333,6 +352,17 @@ define i1 @test10_struct_arr_noinbounds_i64(i64 %x) {
    131   ret i1 %r
    132 }
    133 
    134 +define i1 @test10_struct_arr_noarrayty(i32 %x) {
    135 +; CHECK-LABEL: @test10_struct_arr_noarrayty(
    136 +; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[X:%.*]], 1
    137 +; CHECK-NEXT:    ret i1 [[R]]
    138 +;
    139 +  %p = getelementptr inbounds %Foo, ptr @GStructArr, i32 %x, i32 2
    140 +  %q = load i32, ptr %p
    141 +  %r = icmp eq i32 %q, 9
    142 +  ret i1 %r
    143 +}
    144 +
    145 @table = internal constant [2 x ptr] [ptr @g, ptr getelementptr (i8, ptr @g, i64 4)], align 16
    146 @g = external global [2 x i32]
    147 
    148 -- 
    149 2.51.0