[llvm-branch-commits] [llvm] 09ac575 - [InstCombine] support trunc to i1 cond in foldCmpLoadFromIndexedGlobal (#234284)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Oct 22 09:48:09 PDT 2026


Author: Andreas Jonson
Date: 2026-10-22T15:59:12Z
New Revision: 09ac575f937883b1d3ca1ec9d5b662e57087f847

URL: https://github.com/llvm/llvm-project/commit/09ac575f937883b1d3ca1ec9d5b662e57087f847
DIFF: https://github.com/llvm/llvm-project/commit/09ac575f937883b1d3ca1ec9d5b662e57087f847.diff

LOG: [InstCombine] support trunc to i1 cond in foldCmpLoadFromIndexedGlobal (#234284)

proof: https://alive2.llvm.org/ce/z/km3mx_

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
    llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/lib/Transforms/InstCombine/InstCombineInternal.h
    llvm/test/Transforms/InstCombine/load-cmp.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 76113f4a6bdad..647c5b6d589e1 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -1381,6 +1381,15 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
     return new ICmpInst(ICmpInst::ICMP_UGE, V1, Right);
   }
 
+  if (DestTy->isIntegerTy(1))
+    if (auto *LI = dyn_cast<LoadInst>(Src))
+      if (auto *GEP = dyn_cast<GetElementPtrInst>(LI->getOperand(0))) {
+        if (Instruction *Res = foldCmpLoadFromIndexedGlobal(
+                LI, GEP, ICmpInst::ICMP_NE, ConstantInt::getNullValue(SrcTy),
+                Trunc, ConstantInt::get(cast<IntegerType>(SrcTy), 1)))
+          return Res;
+      }
+
   return Changed ? &Trunc : nullptr;
 }
 

diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 4101c3e7936c4..8a2d8c5c3fb33 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -118,7 +118,8 @@ static bool isSignTest(ICmpInst::Predicate &Pred, const APInt &C) {
 /// Even if there are multiple uses, they can often be sunk into the block
 /// guarded by the icmp.
 Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
-    LoadInst *LI, GetElementPtrInst *GEP, CmpInst &ICI, ConstantInt *AndCst) {
+    LoadInst *LI, GetElementPtrInst *GEP, CmpPredicate Pred, Constant *RHSC,
+    Instruction &CtxI, ConstantInt *AndCst) {
   auto *GV = dyn_cast<GlobalVariable>(getUnderlyingObject(GEP));
   if (LI->isVolatile() || !GV || !GV->isConstant() ||
       !GV->hasDefinitiveInitializer())
@@ -195,7 +196,6 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
   uint64_t MagicBitvector = 0;
 
   // Scan the array and see if one of our patterns matches.
-  Constant *CompareRHS = cast<Constant>(ICI.getOperand(1));
   APInt Offset = ConstOffset;
   for (unsigned i = 0, e = ArrayElementCount; i != e; ++i, Offset += Stride) {
     Constant *Elt = ConstantFoldLoadFromConst(Init, EltTy, Offset, DL);
@@ -210,8 +210,7 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
     }
 
     // Find out if the comparison would be true or false for the i'th element.
-    Constant *C = ConstantFoldCompareInstOperands(ICI.getPredicate(), Elt,
-                                                  CompareRHS, DL, &TLI);
+    Constant *C = ConstantFoldCompareInstOperands(Pred, Elt, RHSC, DL, &TLI);
     if (!C)
       return nullptr;
 
@@ -310,7 +309,7 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
     Idx = MaskIdx(Idx);
     // None true -> false.
     if (FirstTrueElement == Undefined)
-      return replaceInstUsesWith(ICI, Builder.getFalse());
+      return replaceInstUsesWith(CtxI, Builder.getFalse());
 
     Value *FirstTrueIdx = ConstantInt::get(Idx->getType(), FirstTrueElement);
 
@@ -331,7 +330,7 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
     Idx = MaskIdx(Idx);
     // None false -> true.
     if (FirstFalseElement == Undefined)
-      return replaceInstUsesWith(ICI, Builder.getTrue());
+      return replaceInstUsesWith(CtxI, Builder.getTrue());
 
     Value *FirstFalseIdx = ConstantInt::get(Idx->getType(), FirstFalseElement);
 
@@ -1996,7 +1995,9 @@ Instruction *InstCombinerImpl::foldICmpAndConstant(ICmpInst &Cmp,
   if (auto *C2 = dyn_cast<ConstantInt>(Y))
     if (auto *LI = dyn_cast<LoadInst>(X))
       if (auto *GEP = dyn_cast<GetElementPtrInst>(LI->getOperand(0)))
-        if (Instruction *Res = foldCmpLoadFromIndexedGlobal(LI, GEP, Cmp, C2))
+        if (Instruction *Res = foldCmpLoadFromIndexedGlobal(
+                LI, GEP, Cmp.getPredicate(), cast<Constant>(Cmp.getOperand(1)),
+                Cmp, C2))
           return Res;
 
   if (!Cmp.isEquality())
@@ -4513,8 +4514,8 @@ Instruction *InstCombinerImpl::foldICmpInstWithConstantNotInt(ICmpInst &I) {
     // Try to optimize things like "A[i] > 4" to index computations.
     if (GetElementPtrInst *GEP =
             dyn_cast<GetElementPtrInst>(LHSI->getOperand(0)))
-      if (Instruction *Res =
-              foldCmpLoadFromIndexedGlobal(cast<LoadInst>(LHSI), GEP, I))
+      if (Instruction *Res = foldCmpLoadFromIndexedGlobal(
+              cast<LoadInst>(LHSI), GEP, I.getPredicate(), RHSC, I))
         return Res;
     break;
   }
@@ -9490,8 +9491,8 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
       break;
     case Instruction::Load:
       if (auto *GEP = dyn_cast<GetElementPtrInst>(LHSI->getOperand(0)))
-        if (Instruction *Res =
-                foldCmpLoadFromIndexedGlobal(cast<LoadInst>(LHSI), GEP, I))
+        if (Instruction *Res = foldCmpLoadFromIndexedGlobal(
+                cast<LoadInst>(LHSI), GEP, I.getPredicate(), RHSC, I))
           return Res;
       break;
     case Instruction::FPTrunc:

diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index ae0a77bd5be86..161d0c651598b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -738,7 +738,8 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
   bool foldAllocaCmp(AllocaInst *Alloca);
   Instruction *foldCmpLoadFromIndexedGlobal(LoadInst *LI,
                                             GetElementPtrInst *GEP,
-                                            CmpInst &ICI,
+                                            CmpPredicate Pred, Constant *RHSC,
+                                            Instruction &CtxI,
                                             ConstantInt *AndCst = nullptr);
   Instruction *foldFCmpIntToFPConst(FCmpInst &I, Instruction *LHSI,
                                     Constant *RHSC);

diff  --git a/llvm/test/Transforms/InstCombine/load-cmp.ll b/llvm/test/Transforms/InstCombine/load-cmp.ll
index e9a9f7bf87a51..4c3baadcbc9b2 100644
--- a/llvm/test/Transforms/InstCombine/load-cmp.ll
+++ b/llvm/test/Transforms/InstCombine/load-cmp.ll
@@ -4,6 +4,10 @@
 @G16 = internal constant [10 x i16] [i16 35, i16 82, i16 69, i16 81, i16 85,
   i16 73, i16 82, i16 69, i16 68, i16 0]
 
+ at G16_vec = internal constant [10 x <2 x i16>] [<2 x i16> <i16 35, i16 35>,<2 x i16> <i16 82, i16 82>,
+  <2 x i16> <i16 69, i16 69>, <2 x i16> <i16 81, i16 81>, <2 x i16> <i16 85, i16 85>,<2 x i16> <i16 73, i16 73>,
+  <2 x i16> <i16 82, i16 82>,<2 x i16> <i16 69, i16 69>,<2 x i16> <i16 68, i16 68>, <2 x i16> <i16 0, i16 0>]
+
 @G16_as1 = internal addrspace(1) constant [10 x i16] [i16 35, i16 82, i16 69, i16 81, i16 85,
   i16 73, i16 82, i16 69, i16 68, i16 0]
 
@@ -633,6 +637,31 @@ define i1 @cmp_load_shifted_index(i32 %X) {
   ret i1 %cmp
 }
 
+define i1 @trunc_load_from_indexed_global(i32 %idx) {
+; CHECK-LABEL: @trunc_load_from_indexed_global(
+; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 189, [[IDX:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = trunc i32 [[TMP1]] to i1
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %gep = getelementptr inbounds i16, ptr @G16, i32 %idx
+  %v = load i16, ptr %gep
+  %r = trunc i16 %v to i1
+  ret i1 %r
+}
+
+define <2 x i1> @trunc_load_from_indexed_global_vec(i32 %idx) {
+; CHECK-LABEL: @trunc_load_from_indexed_global_vec(
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [4 x i8], ptr @G16_vec, i32 [[TMP1:%.*]]
+; CHECK-NEXT:    [[V:%.*]] = load <2 x i16>, ptr [[GEP]], align 4
+; CHECK-NEXT:    [[R:%.*]] = trunc <2 x i16> [[V]] to <2 x i1>
+; CHECK-NEXT:    ret <2 x i1> [[R]]
+;
+  %gep = getelementptr inbounds <2 x i16>, ptr @G16_vec, i32 %idx
+  %v = load <2 x i16>, ptr %gep
+  %r = trunc <2 x i16> %v to <2 x i1>
+  ret <2 x i1> %r
+}
+
 define i1 @cmp_load_multiplied_index_noflags(i32 %X) {
 ; CHECK-LABEL: @cmp_load_multiplied_index_noflags(
 ; CHECK-NEXT:    [[GEP_IDX:%.*]] = mul i32 [[X:%.*]], 6


        


More information about the llvm-branch-commits mailing list