[llvm] [AggressiveInstCombine] Fix crash when folding consecutive loads into a type smaller than the combined load (PR #207229)

Kyungtak Woo via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 8 19:50:07 PDT 2026


https://github.com/kevinwkt updated https://github.com/llvm/llvm-project/pull/207229

>From 819bab56079b73ae294313ab6c37897ae33967c8 Mon Sep 17 00:00:00 2001
From: Kyungtak Woo <kevinwkt at google.com>
Date: Thu, 2 Jul 2026 16:45:06 +0000
Subject: [PATCH 1/6] fix: use CreateZExtOrTrunc in AggressiveInstCombine to
 support truncation during load combination

---
 .../AggressiveInstCombine.cpp                 |  2 +-
 .../AggressiveInstCombine/X86/or-load.ll      | 71 ++++++++++++++++---
 2 files changed, 63 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index 0ebecf8bcd260..69920f4a79552 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -1438,7 +1438,7 @@ static bool foldConsecutiveLoads(Instruction &I, const DataLayout &DL,
   Value *NewOp = NewLoad;
   // Check if zero extend needed.
   if (LOps.ZextType)
-    NewOp = Builder.CreateZExt(NewOp, LOps.ZextType);
+    NewOp = Builder.CreateZExtOrTrunc(NewOp, LOps.ZextType);
 
   // Check if shift needed. We need to shift with the amount of load1
   // shift if not zero.
diff --git a/llvm/test/Transforms/AggressiveInstCombine/X86/or-load.ll b/llvm/test/Transforms/AggressiveInstCombine/X86/or-load.ll
index 73ff729900058..e30c30f2e364e 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/X86/or-load.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/X86/or-load.ll
@@ -1377,19 +1377,19 @@ entry:
 
 define i32 @loadCombine_4consecutive_metadata(ptr %p, ptr %pstr) {
 ; LE-LABEL: @loadCombine_4consecutive_metadata(
-; LE-NEXT:    [[L1:%.*]] = load i32, ptr [[P:%.*]], align 1, !alias.scope [[META0:![0-9]+]]
-; LE-NEXT:    store i32 25, ptr [[PSTR:%.*]], align 4, !noalias [[META0]]
+; LE-NEXT:    [[L1:%.*]] = load i32, ptr [[P:%.*]], align 1, !alias.scope [[META1:![0-9]+]]
+; LE-NEXT:    store i32 25, ptr [[PSTR:%.*]], align 4, !noalias [[META1]]
 ; LE-NEXT:    ret i32 [[L1]]
 ;
 ; BE-LABEL: @loadCombine_4consecutive_metadata(
 ; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
 ; BE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
 ; BE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
-; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1, !alias.scope [[META0:![0-9]+]]
-; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1, !alias.scope [[META0]]
-; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1, !alias.scope [[META0]]
-; BE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1, !alias.scope [[META0]]
-; BE-NEXT:    store i32 25, ptr [[PSTR:%.*]], align 4, !noalias [[META0]]
+; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1, !alias.scope [[META1:![0-9]+]]
+; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1, !alias.scope [[META1]]
+; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1, !alias.scope [[META1]]
+; BE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1, !alias.scope [[META1]]
+; BE-NEXT:    store i32 25, ptr [[PSTR:%.*]], align 4, !noalias [[META1]]
 ; BE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
 ; BE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
 ; BE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
@@ -2223,7 +2223,7 @@ define i32 @loadCombine_4consecutive_badinsert4(ptr %p) {
 ; LE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
 ; LE-NEXT:    [[C1:%.*]] = load i8, ptr [[P1]], align 1
 ; LE-NEXT:    [[CMP:%.*]] = icmp eq i8 [[C1]], 0
-; LE-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[BB2:%.*]]
+; LE-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[BB2:%.*]], !prof [[PROF4:![0-9]+]]
 ; LE:       bb2:
 ; LE-NEXT:    [[L1:%.*]] = load i32, ptr [[P1]], align 1
 ; LE-NEXT:    br label [[END]]
@@ -2236,7 +2236,7 @@ define i32 @loadCombine_4consecutive_badinsert4(ptr %p) {
 ; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
 ; BE-NEXT:    [[C1:%.*]] = load i8, ptr [[P1]], align 1
 ; BE-NEXT:    [[CMP:%.*]] = icmp eq i8 [[C1]], 0
-; BE-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[BB2:%.*]]
+; BE-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[BB2:%.*]], !prof [[PROF4:![0-9]+]]
 ; BE:       bb2:
 ; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P1]], align 1
 ; BE-NEXT:    [[C2:%.*]] = zext i8 [[L1]] to i32
@@ -2629,3 +2629,56 @@ entry:
   %res = lshr i64 %or2, 32
   ret i64 %res
 }
+
+define i16 @combine_four_i8_loads_i16_poison(ptr %p) {
+; LE-LABEL: @combine_four_i8_loads_i16_poison(
+; LE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 2
+; LE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i64 3
+; LE-NEXT:    [[L1:%.*]] = load i32, ptr [[P]], align 1
+; LE-NEXT:    [[TMP1:%.*]] = trunc i32 [[L1]] to i16
+; LE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; LE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; LE-NEXT:    [[Z3:%.*]] = zext i8 [[L3]] to i16
+; LE-NEXT:    [[Z4:%.*]] = zext i8 [[L4]] to i16
+; LE-NEXT:    ret i16 [[TMP1]]
+;
+; BE-LABEL: @combine_four_i8_loads_i16_poison(
+; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
+; BE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 2
+; BE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i64 3
+; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1
+; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1
+; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
+; BE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
+; BE-NEXT:    [[Z1:%.*]] = zext i8 [[L1]] to i16
+; BE-NEXT:    [[Z2:%.*]] = zext i8 [[L2]] to i16
+; BE-NEXT:    [[Z3:%.*]] = zext i8 [[L3]] to i16
+; BE-NEXT:    [[Z4:%.*]] = zext i8 [[L4]] to i16
+; BE-NEXT:    [[SH2:%.*]] = shl i16 [[Z2]], 8
+; BE-NEXT:    [[OR1:%.*]] = or i16 [[Z1]], [[SH2]]
+; BE-NEXT:    [[SH3:%.*]] = shl i16 [[Z3]], 16
+; BE-NEXT:    [[OR2:%.*]] = or i16 [[OR1]], [[SH3]]
+; BE-NEXT:    [[SH4:%.*]] = shl i16 [[Z4]], 24
+; BE-NEXT:    [[OR3:%.*]] = or i16 [[OR2]], [[SH4]]
+; BE-NEXT:    ret i16 [[OR3]]
+;
+  %p1 = getelementptr i8, ptr %p, i64 1
+  %p2 = getelementptr i8, ptr %p, i64 2
+  %p3 = getelementptr i8, ptr %p, i64 3
+  %l1 = load i8, ptr %p
+  %l2 = load i8, ptr %p1
+  %l3 = load i8, ptr %p2
+  %l4 = load i8, ptr %p3
+  %z1 = zext i8 %l1 to i16
+  %z2 = zext i8 %l2 to i16
+  %z3 = zext i8 %l3 to i16
+  %z4 = zext i8 %l4 to i16
+  %sh2 = shl i16 %z2, 8
+  %or1 = or i16 %z1, %sh2
+  %sh3 = shl i16 %z3, 16
+  %or2 = or i16 %or1, %sh3
+  %sh4 = shl i16 %z4, 24
+  %or3 = or i16 %or2, %sh4
+  ret i16 %or3
+}
+

>From f83db8f6868c858ffff89a22b53a4dae9a13cde9 Mon Sep 17 00:00:00 2001
From: Kyungtak Woo <kevinwkt at google.com>
Date: Thu, 2 Jul 2026 17:37:59 +0000
Subject: [PATCH 2/6] make tests without profcheck

---
 .../AggressiveInstCombine/X86/or-load.ll       | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/llvm/test/Transforms/AggressiveInstCombine/X86/or-load.ll b/llvm/test/Transforms/AggressiveInstCombine/X86/or-load.ll
index e30c30f2e364e..8f0b5d62fab72 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/X86/or-load.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/X86/or-load.ll
@@ -1377,19 +1377,19 @@ entry:
 
 define i32 @loadCombine_4consecutive_metadata(ptr %p, ptr %pstr) {
 ; LE-LABEL: @loadCombine_4consecutive_metadata(
-; LE-NEXT:    [[L1:%.*]] = load i32, ptr [[P:%.*]], align 1, !alias.scope [[META1:![0-9]+]]
-; LE-NEXT:    store i32 25, ptr [[PSTR:%.*]], align 4, !noalias [[META1]]
+; LE-NEXT:    [[L1:%.*]] = load i32, ptr [[P:%.*]], align 1, !alias.scope [[META0:![0-9]+]]
+; LE-NEXT:    store i32 25, ptr [[PSTR:%.*]], align 4, !noalias [[META0]]
 ; LE-NEXT:    ret i32 [[L1]]
 ;
 ; BE-LABEL: @loadCombine_4consecutive_metadata(
 ; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i32 1
 ; BE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i32 2
 ; BE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i32 3
-; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1, !alias.scope [[META1:![0-9]+]]
-; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1, !alias.scope [[META1]]
-; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1, !alias.scope [[META1]]
-; BE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1, !alias.scope [[META1]]
-; BE-NEXT:    store i32 25, ptr [[PSTR:%.*]], align 4, !noalias [[META1]]
+; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P]], align 1, !alias.scope [[META0:![0-9]+]]
+; BE-NEXT:    [[L2:%.*]] = load i8, ptr [[P1]], align 1, !alias.scope [[META0]]
+; BE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1, !alias.scope [[META0]]
+; BE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1, !alias.scope [[META0]]
+; BE-NEXT:    store i32 25, ptr [[PSTR:%.*]], align 4, !noalias [[META0]]
 ; BE-NEXT:    [[E1:%.*]] = zext i8 [[L1]] to i32
 ; BE-NEXT:    [[E2:%.*]] = zext i8 [[L2]] to i32
 ; BE-NEXT:    [[E3:%.*]] = zext i8 [[L3]] to i32
@@ -2223,7 +2223,7 @@ define i32 @loadCombine_4consecutive_badinsert4(ptr %p) {
 ; LE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
 ; LE-NEXT:    [[C1:%.*]] = load i8, ptr [[P1]], align 1
 ; LE-NEXT:    [[CMP:%.*]] = icmp eq i8 [[C1]], 0
-; LE-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[BB2:%.*]], !prof [[PROF4:![0-9]+]]
+; LE-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[BB2:%.*]]
 ; LE:       bb2:
 ; LE-NEXT:    [[L1:%.*]] = load i32, ptr [[P1]], align 1
 ; LE-NEXT:    br label [[END]]
@@ -2236,7 +2236,7 @@ define i32 @loadCombine_4consecutive_badinsert4(ptr %p) {
 ; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1
 ; BE-NEXT:    [[C1:%.*]] = load i8, ptr [[P1]], align 1
 ; BE-NEXT:    [[CMP:%.*]] = icmp eq i8 [[C1]], 0
-; BE-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[BB2:%.*]], !prof [[PROF4:![0-9]+]]
+; BE-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[BB2:%.*]]
 ; BE:       bb2:
 ; BE-NEXT:    [[L1:%.*]] = load i8, ptr [[P1]], align 1
 ; BE-NEXT:    [[C2:%.*]] = zext i8 [[L1]] to i32

>From a9d7bb157089dc673c7f9b62798fb2dae93bfcf6 Mon Sep 17 00:00:00 2001
From: Kyungtak Woo <kevinwkt at google.com>
Date: Thu, 2 Jul 2026 20:54:01 +0000
Subject: [PATCH 3/6] docs: update comment on truncation

---
 .../Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index 69920f4a79552..2e10de53c6aea 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -1436,7 +1436,7 @@ static bool foldConsecutiveLoads(Instruction &I, const DataLayout &DL,
     NewLoad->setAAMetadata(LOps.AATags);
 
   Value *NewOp = NewLoad;
-  // Check if zero extend needed.
+  // Check if zero extend or truncate needed.
   if (LOps.ZextType)
     NewOp = Builder.CreateZExtOrTrunc(NewOp, LOps.ZextType);
 

>From 6ed7db7d0a712234c4c3e7bf770d96a108631c5e Mon Sep 17 00:00:00 2001
From: Kyungtak Woo <kevinwkt at google.com>
Date: Tue, 7 Jul 2026 02:06:24 +0000
Subject: [PATCH 4/6] fix: change to reject if load size is larger than the
 target type

---
 .../AggressiveInstCombine.cpp                  | 18 +++++++++++++++++-
 .../AggressiveInstCombine/X86/or-load.ll       |  4 +---
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index 2e10de53c6aea..edc4822201ebe 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -1235,7 +1235,7 @@ struct LoadOps {
   bool FoundRoot = false;
   uint64_t LoadSize = 0;
   uint64_t Shift = 0;
-  Type *ZextType;
+  Type *ZextType = nullptr;
   AAMDNodes AATags;
 };
 
@@ -1273,6 +1273,22 @@ static bool foldLoadsRecursive(Value *V, LoadOps &LOps, const DataLayout &DL,
   }
   LoadInst *LI2 = dyn_cast<LoadInst>(L2);
 
+  // Reject early if the combined size of the loads exceeds the target type
+  // size. This avoids attempting to emit an invalid ZExt (from wider to
+  // narrower type) when out-of-bounds shifts lead to matching too many loads.
+  if (LI2) {
+    uint64_t CurrentLoadSize = 0;
+    if (LOps.FoundRoot)
+      CurrentLoadSize = LOps.LoadSize;
+    else if (LI1)
+      CurrentLoadSize = LI1->getType()->getPrimitiveSizeInBits();
+
+    uint64_t LI2Size = LI2->getType()->getPrimitiveSizeInBits();
+    uint64_t TargetSize = X->getType()->getScalarSizeInBits();
+    if (CurrentLoadSize + LI2Size > TargetSize)
+      return false;
+  }
+
   // Check if loads are same, atomic, volatile and having same address space.
   if (LI1 == LI2 || !LI1 || !LI2 || !LI1->isSimple() || !LI2->isSimple() ||
       LI1->getPointerAddressSpace() != LI2->getPointerAddressSpace())
diff --git a/llvm/test/Transforms/AggressiveInstCombine/X86/or-load.ll b/llvm/test/Transforms/AggressiveInstCombine/X86/or-load.ll
index 8f0b5d62fab72..d8ab24c7b7eb1 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/X86/or-load.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/X86/or-load.ll
@@ -2634,13 +2634,11 @@ define i16 @combine_four_i8_loads_i16_poison(ptr %p) {
 ; LE-LABEL: @combine_four_i8_loads_i16_poison(
 ; LE-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 2
 ; LE-NEXT:    [[P3:%.*]] = getelementptr i8, ptr [[P]], i64 3
-; LE-NEXT:    [[L1:%.*]] = load i32, ptr [[P]], align 1
-; LE-NEXT:    [[TMP1:%.*]] = trunc i32 [[L1]] to i16
 ; LE-NEXT:    [[L3:%.*]] = load i8, ptr [[P2]], align 1
 ; LE-NEXT:    [[L4:%.*]] = load i8, ptr [[P3]], align 1
 ; LE-NEXT:    [[Z3:%.*]] = zext i8 [[L3]] to i16
 ; LE-NEXT:    [[Z4:%.*]] = zext i8 [[L4]] to i16
-; LE-NEXT:    ret i16 [[TMP1]]
+; LE-NEXT:    ret i16 poison
 ;
 ; BE-LABEL: @combine_four_i8_loads_i16_poison(
 ; BE-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 1

>From d59d3018bbff12595c2b9aedf57d7ce655860c5d Mon Sep 17 00:00:00 2001
From: Kyungtak Woo <kevinwkt at google.com>
Date: Wed, 8 Jul 2026 22:02:03 +0000
Subject: [PATCH 5/6] address review comments

---
 .../AggressiveInstCombine.cpp                 | 30 +++++++------------
 1 file changed, 10 insertions(+), 20 deletions(-)

diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index edc4822201ebe..99017f77843c1 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -1235,7 +1235,7 @@ struct LoadOps {
   bool FoundRoot = false;
   uint64_t LoadSize = 0;
   uint64_t Shift = 0;
-  Type *ZextType = nullptr;
+  Type *ZextType;
   AAMDNodes AATags;
 };
 
@@ -1273,22 +1273,6 @@ static bool foldLoadsRecursive(Value *V, LoadOps &LOps, const DataLayout &DL,
   }
   LoadInst *LI2 = dyn_cast<LoadInst>(L2);
 
-  // Reject early if the combined size of the loads exceeds the target type
-  // size. This avoids attempting to emit an invalid ZExt (from wider to
-  // narrower type) when out-of-bounds shifts lead to matching too many loads.
-  if (LI2) {
-    uint64_t CurrentLoadSize = 0;
-    if (LOps.FoundRoot)
-      CurrentLoadSize = LOps.LoadSize;
-    else if (LI1)
-      CurrentLoadSize = LI1->getType()->getPrimitiveSizeInBits();
-
-    uint64_t LI2Size = LI2->getType()->getPrimitiveSizeInBits();
-    uint64_t TargetSize = X->getType()->getScalarSizeInBits();
-    if (CurrentLoadSize + LI2Size > TargetSize)
-      return false;
-  }
-
   // Check if loads are same, atomic, volatile and having same address space.
   if (LI1 == LI2 || !LI1 || !LI2 || !LI1->isSimple() || !LI2->isSimple() ||
       LI1->getPointerAddressSpace() != LI2->getPointerAddressSpace())
@@ -1385,6 +1369,12 @@ static bool foldLoadsRecursive(Value *V, LoadOps &LOps, const DataLayout &DL,
   if ((ShAmt2 - ShAmt1) != ShiftDiff || (Offset2 - Offset1) != PrevSize)
     return false;
 
+  // Reject if the combined size of the loads exceeds the target type size.
+  // This avoids attempting to emit an invalid ZExt (from wider to narrower
+  // type) when out-of-bounds shifts lead to matching too many loads.
+  if (LoadSize1 + LoadSize2 > X->getType()->getScalarSizeInBits())
+    return false;
+
   // Update LOps
   AAMDNodes AATags1 = LOps.AATags;
   AAMDNodes AATags2 = LI2->getAAMetadata();
@@ -1452,9 +1442,9 @@ static bool foldConsecutiveLoads(Instruction &I, const DataLayout &DL,
     NewLoad->setAAMetadata(LOps.AATags);
 
   Value *NewOp = NewLoad;
-  // Check if zero extend or truncate needed.
-  if (LOps.ZextType)
-    NewOp = Builder.CreateZExtOrTrunc(NewOp, LOps.ZextType);
+  // Check if zero extend needed.
+  if (NewOp->getType() != LOps.ZextType)
+    NewOp = Builder.CreateZExt(NewOp, LOps.ZextType);
 
   // Check if shift needed. We need to shift with the amount of load1
   // shift if not zero.

>From 8042ee8a353f1164e12875110acc81119c69fac9 Mon Sep 17 00:00:00 2001
From: Kyungtak Woo <kevinwkt at google.com>
Date: Thu, 9 Jul 2026 02:49:41 +0000
Subject: [PATCH 6/6] fix: get rid of redundant conditional

---
 .../AggressiveInstCombine/AggressiveInstCombine.cpp          | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index 99017f77843c1..3143ad46e8cfd 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -1442,9 +1442,8 @@ static bool foldConsecutiveLoads(Instruction &I, const DataLayout &DL,
     NewLoad->setAAMetadata(LOps.AATags);
 
   Value *NewOp = NewLoad;
-  // Check if zero extend needed.
-  if (NewOp->getType() != LOps.ZextType)
-    NewOp = Builder.CreateZExt(NewOp, LOps.ZextType);
+  // Zero extend if needed.
+  NewOp = Builder.CreateZExt(NewOp, LOps.ZextType);
 
   // Check if shift needed. We need to shift with the amount of load1
   // shift if not zero.



More information about the llvm-commits mailing list