[llvm] [InstCombine] Preserve nneg in foldLogicCastConstant (PR #157865)

Hongyu Chen via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 10 08:40:43 PDT 2025


https://github.com/XChy updated https://github.com/llvm/llvm-project/pull/157865

>From ea84f3fb8cd689c91ede6c8e600bc31c70d4ee33 Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Wed, 10 Sep 2025 20:36:11 +0800
Subject: [PATCH 1/3] Precommit tests

---
 llvm/test/Transforms/InstCombine/or.ll | 66 ++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/or.ll b/llvm/test/Transforms/InstCombine/or.ll
index a5cc933278982..ef30c0525238f 100644
--- a/llvm/test/Transforms/InstCombine/or.ll
+++ b/llvm/test/Transforms/InstCombine/or.ll
@@ -2047,3 +2047,69 @@ define i1 @or_truncs(i8 %x) {
   %or1 = or i1 %trunc1, %trunc2
   ret i1 %or1
 }
+
+define i32 @or_zext_constant(i8 %a) {
+; CHECK-LABEL: @or_zext_constant(
+; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[A:%.*]], 1
+; CHECK-NEXT:    [[AND:%.*]] = zext i8 [[TMP1]] to i32
+; CHECK-NEXT:    ret i32 [[AND]]
+;
+  %zext = zext i8 %a to i32
+  %or = or i32 %zext, 1
+  ret i32 %or
+}
+
+define i32 @or_zext_minus_constant(i8 %a) {
+; CHECK-LABEL: @or_zext_minus_constant(
+; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[A:%.*]], 1
+; CHECK-NEXT:    [[OR:%.*]] = zext i8 [[TMP1]] to i32
+; CHECK-NEXT:    ret i32 [[OR]]
+;
+  %zext = zext i8 %a to i32
+  %or = or i32 %zext, 1
+  ret i32 %or
+}
+
+define i32 @or_zext_nneg_constant(i8 %a) {
+; CHECK-LABEL: @or_zext_nneg_constant(
+; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[A:%.*]], 9
+; CHECK-NEXT:    [[AND:%.*]] = zext i8 [[TMP1]] to i32
+; CHECK-NEXT:    ret i32 [[AND]]
+;
+  %zext = zext nneg i8 %a to i32
+  %or = or i32 %zext, 9
+  ret i32 %or
+}
+
+define <4 x i32> @or_zext_nneg_constant_splat(<4 x i8> %a) {
+; CHECK-LABEL: @or_zext_nneg_constant_splat(
+; CHECK-NEXT:    [[TMP1:%.*]] = or <4 x i8> [[A:%.*]], splat (i8 9)
+; CHECK-NEXT:    [[OR:%.*]] = zext <4 x i8> [[TMP1]] to <4 x i32>
+; CHECK-NEXT:    ret <4 x i32> [[OR]]
+;
+  %zext = zext nneg <4 x i8> %a to <4 x i32>
+  %or = or <4 x i32> %zext, splat (i32 9)
+  ret <4 x i32> %or
+}
+
+define i32 @or_zext_nneg_minus_constant(i8 %a) {
+; CHECK-LABEL: @or_zext_nneg_minus_constant(
+; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[A:%.*]], -9
+; CHECK-NEXT:    [[ZEXT:%.*]] = sext i8 [[TMP1]] to i32
+; CHECK-NEXT:    ret i32 [[ZEXT]]
+;
+  %zext = zext nneg i8 %a to i32
+  %or = or i32 %zext, -9
+  ret i32 %or
+}
+
+define <4 x i32> @or_zext_nneg_minus_constant_splat(<4 x i8> %a) {
+; CHECK-LABEL: @or_zext_nneg_minus_constant_splat(
+; CHECK-NEXT:    [[TMP1:%.*]] = or <4 x i8> [[A:%.*]], splat (i8 -9)
+; CHECK-NEXT:    [[OR:%.*]] = sext <4 x i8> [[TMP1]] to <4 x i32>
+; CHECK-NEXT:    ret <4 x i32> [[OR]]
+;
+  %zext = zext nneg <4 x i8> %a to <4 x i32>
+  %or = or <4 x i32> %zext, splat (i32 -9)
+  ret <4 x i32> %or
+}

>From 9481e45fbca6aaa10fa4d97e7612dd47bf163742 Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Wed, 10 Sep 2025 22:12:16 +0800
Subject: [PATCH 2/3] [InstCombine] Preserve nneg in foldLogicCastConstant

---
 llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 8 ++++++--
 llvm/test/Transforms/InstCombine/or.ll                  | 4 ++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 8b9df62d7c652..2d7524e8018b2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1801,10 +1801,14 @@ static Instruction *foldLogicCastConstant(BinaryOperator &Logic, CastInst *Cast,
   Value *X;
   auto &DL = IC.getDataLayout();
   if (match(Cast, m_OneUse(m_ZExt(m_Value(X))))) {
-    if (Constant *TruncC = getLosslessUnsignedTrunc(C, SrcTy, DL)) {
+    PreservedCastFlags Flags;
+    if (Constant *TruncC = getLosslessUnsignedTrunc(C, SrcTy, DL, &Flags)) {
       // LogicOpc (zext X), C --> zext (LogicOpc X, C)
       Value *NewOp = IC.Builder.CreateBinOp(LogicOpc, X, TruncC);
-      return new ZExtInst(NewOp, DestTy);
+      auto *ZExt = new ZExtInst(NewOp, DestTy);
+      ZExt->setNonNeg(Flags.NNeg);
+      ZExt->andIRFlags(Cast);
+      return ZExt;
     }
   }
 
diff --git a/llvm/test/Transforms/InstCombine/or.ll b/llvm/test/Transforms/InstCombine/or.ll
index ef30c0525238f..60a2c786c8bb4 100644
--- a/llvm/test/Transforms/InstCombine/or.ll
+++ b/llvm/test/Transforms/InstCombine/or.ll
@@ -2073,7 +2073,7 @@ define i32 @or_zext_minus_constant(i8 %a) {
 define i32 @or_zext_nneg_constant(i8 %a) {
 ; CHECK-LABEL: @or_zext_nneg_constant(
 ; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[A:%.*]], 9
-; CHECK-NEXT:    [[AND:%.*]] = zext i8 [[TMP1]] to i32
+; CHECK-NEXT:    [[AND:%.*]] = zext nneg i8 [[TMP1]] to i32
 ; CHECK-NEXT:    ret i32 [[AND]]
 ;
   %zext = zext nneg i8 %a to i32
@@ -2084,7 +2084,7 @@ define i32 @or_zext_nneg_constant(i8 %a) {
 define <4 x i32> @or_zext_nneg_constant_splat(<4 x i8> %a) {
 ; CHECK-LABEL: @or_zext_nneg_constant_splat(
 ; CHECK-NEXT:    [[TMP1:%.*]] = or <4 x i8> [[A:%.*]], splat (i8 9)
-; CHECK-NEXT:    [[OR:%.*]] = zext <4 x i8> [[TMP1]] to <4 x i32>
+; CHECK-NEXT:    [[OR:%.*]] = zext nneg <4 x i8> [[TMP1]] to <4 x i32>
 ; CHECK-NEXT:    ret <4 x i32> [[OR]]
 ;
   %zext = zext nneg <4 x i8> %a to <4 x i32>

>From cfdfb87bb7283e8d7274ba6a7483cdb240a3154f Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Wed, 10 Sep 2025 23:40:25 +0800
Subject: [PATCH 3/3] correct test

---
 llvm/test/Transforms/InstCombine/or.ll | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/test/Transforms/InstCombine/or.ll b/llvm/test/Transforms/InstCombine/or.ll
index 60a2c786c8bb4..6b090e982af0a 100644
--- a/llvm/test/Transforms/InstCombine/or.ll
+++ b/llvm/test/Transforms/InstCombine/or.ll
@@ -2061,12 +2061,12 @@ define i32 @or_zext_constant(i8 %a) {
 
 define i32 @or_zext_minus_constant(i8 %a) {
 ; CHECK-LABEL: @or_zext_minus_constant(
-; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[A:%.*]], 1
-; CHECK-NEXT:    [[OR:%.*]] = zext i8 [[TMP1]] to i32
-; CHECK-NEXT:    ret i32 [[OR]]
+; CHECK-NEXT:    [[OR:%.*]] = zext i8 [[TMP1:%.*]] to i32
+; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[OR]], -9
+; CHECK-NEXT:    ret i32 [[OR1]]
 ;
   %zext = zext i8 %a to i32
-  %or = or i32 %zext, 1
+  %or = or i32 %zext, -9
   ret i32 %or
 }
 



More information about the llvm-commits mailing list