Skip to content

[InstCombine] Refactor the code for folding logicop and sext/zext. NFC. #137132

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 25, 2025

Conversation

tclin914
Copy link
Contributor

This refactoring is for more easily adding the code to preserve disjoint or in the PR #136815.

Both casts must have one use for folding logicop and sext/zext when the src type differ to avoid creating an extra instruction. If the src type of casts are the same, only one of the casts needs to have one use. This PR also adds more tests for the same src type.

This refactoring is for more easily adding the code to preserve disjoint or
in the PR llvm#136815.

Both casts must have one use for folding logicop and sext/zext when the
src type differ to avoid creating an extra instruction. If the src type
of casts are the same, only one of the casts needs to have one use.
This PR also adds more tests for the same src type.
@tclin914 tclin914 requested review from lukel97, dtcxzyw and topperc April 24, 2025 07:55
@tclin914 tclin914 requested a review from nikic as a code owner April 24, 2025 07:55
@llvmbot llvmbot added llvm:instcombine Covers the InstCombine, InstSimplify and AggressiveInstCombine passes llvm:transforms labels Apr 24, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 24, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Jim Lin (tclin914)

Changes

This refactoring is for more easily adding the code to preserve disjoint or in the PR #136815.

Both casts must have one use for folding logicop and sext/zext when the src type differ to avoid creating an extra instruction. If the src type of casts are the same, only one of the casts needs to have one use. This PR also adds more tests for the same src type.


Full diff: https://github.com/llvm/llvm-project/pull/137132.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (+29-18)
  • (modified) llvm/test/Transforms/InstCombine/and-xor-or.ll (+224-12)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index f1b225c0f238a..3c0836da3c343 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1846,34 +1846,45 @@ Instruction *InstCombinerImpl::foldCastedBitwiseLogic(BinaryOperator &I) {
   if (CastOpcode != Cast1->getOpcode())
     return nullptr;
 
-  // If the source types do not match, but the casts are matching extends, we
-  // can still narrow the logic op.
-  if (SrcTy != Cast1->getSrcTy()) {
-    Value *X, *Y;
-    if (match(Cast0, m_OneUse(m_ZExtOrSExt(m_Value(X)))) &&
-        match(Cast1, m_OneUse(m_ZExtOrSExt(m_Value(Y))))) {
-      // Cast the narrower source to the wider source type.
-      unsigned XNumBits = X->getType()->getScalarSizeInBits();
-      unsigned YNumBits = Y->getType()->getScalarSizeInBits();
-      if (XNumBits < YNumBits)
+  // Can't fold it profitably if no one of casts has one use.
+  if (!Cast0->hasOneUse() && !Cast1->hasOneUse())
+    return nullptr;
+
+  Value *X, *Y;
+  if (match(Cast0, m_ZExtOrSExt(m_Value(X))) &&
+      match(Cast1, m_ZExtOrSExt(m_Value(Y)))) {
+    // Cast the narrower source to the wider source type.
+    unsigned XNumBits = X->getType()->getScalarSizeInBits();
+    unsigned YNumBits = Y->getType()->getScalarSizeInBits();
+    if (XNumBits != YNumBits) {
+      // Cast the narrower source to the wider source type only if both of casts
+      // have one use to avoid creating an extra instruction.
+      if (!Cast0->hasOneUse() || !Cast1->hasOneUse())
+        return nullptr;
+
+      // If the source types do not match, but the casts are matching extends,
+      // we can still narrow the logic op.
+      if (XNumBits < YNumBits) {
         X = Builder.CreateCast(CastOpcode, X, Y->getType());
-      else
+      } else if (YNumBits < XNumBits) {
         Y = Builder.CreateCast(CastOpcode, Y, X->getType());
-      // Do the logic op in the intermediate width, then widen more.
-      Value *NarrowLogic = Builder.CreateBinOp(LogicOpc, X, Y);
-      return CastInst::Create(CastOpcode, NarrowLogic, DestTy);
+      }
     }
 
-    // Give up for other cast opcodes.
-    return nullptr;
+    // Do the logic op in the intermediate width, then widen more.
+    Value *NarrowLogic = Builder.CreateBinOp(LogicOpc, X, Y, I.getName());
+    return CastInst::Create(CastOpcode, NarrowLogic, DestTy);
   }
 
+  // If the src type of casts are different, give up for other cast opcodes.
+  if (SrcTy != Cast1->getSrcTy())
+    return nullptr;
+
   Value *Cast0Src = Cast0->getOperand(0);
   Value *Cast1Src = Cast1->getOperand(0);
 
   // fold logic(cast(A), cast(B)) -> cast(logic(A, B))
-  if ((Cast0->hasOneUse() || Cast1->hasOneUse()) &&
-      shouldOptimizeCast(Cast0) && shouldOptimizeCast(Cast1)) {
+  if (shouldOptimizeCast(Cast0) && shouldOptimizeCast(Cast1)) {
     Value *NewOp = Builder.CreateBinOp(LogicOpc, Cast0Src, Cast1Src,
                                        I.getName());
     return CastInst::Create(CastOpcode, NewOp, DestTy);
diff --git a/llvm/test/Transforms/InstCombine/and-xor-or.ll b/llvm/test/Transforms/InstCombine/and-xor-or.ll
index 5a58995f6c315..74d1f2119a2ad 100644
--- a/llvm/test/Transforms/InstCombine/and-xor-or.ll
+++ b/llvm/test/Transforms/InstCombine/and-xor-or.ll
@@ -2,6 +2,8 @@
 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
 
 declare void @use(i32)
+declare void @use_i16(i8)
+declare void @use_2xi16(<2 x i16>)
 declare void @use_i8(i8)
 declare void @use_i1(i1)
 
@@ -4250,8 +4252,8 @@ define i16 @and_zext_zext(i8 %x, i4 %y) {
 ; CHECK-LABEL: define {{[^@]+}}@and_zext_zext
 ; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i4 [[Y]] to i8
-; CHECK-NEXT:    [[TMP2:%.*]] = and i8 [[X]], [[TMP1]]
-; CHECK-NEXT:    [[R:%.*]] = zext nneg i8 [[TMP2]] to i16
+; CHECK-NEXT:    [[R1:%.*]] = and i8 [[X]], [[TMP1]]
+; CHECK-NEXT:    [[R:%.*]] = zext nneg i8 [[R1]] to i16
 ; CHECK-NEXT:    ret i16 [[R]]
 ;
   %zx = zext i8 %x to i16
@@ -4260,12 +4262,41 @@ define i16 @and_zext_zext(i8 %x, i4 %y) {
   ret i16 %r
 }
 
+define i16 @and_zext_zext_2(i8 %x, i8 %y) {
+; CHECK-LABEL: define {{[^@]+}}@and_zext_zext_2
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[R1:%.*]] = and i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[R:%.*]] = zext i8 [[R1]] to i16
+; CHECK-NEXT:    ret i16 [[R]]
+;
+  %zx = zext i8 %x to i16
+  %zy = zext i8 %y to i16
+  %r = and i16 %zx, %zy
+  ret i16 %r
+}
+
+define i16 @and_zext_zext_2_use1(i8 %x, i8 %y) {
+; CHECK-LABEL: define {{[^@]+}}@and_zext_zext_2_use1
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[ZX:%.*]] = zext i8 [[X]] to i16
+; CHECK-NEXT:    call void @use_i16(i16 [[ZX]])
+; CHECK-NEXT:    [[R1:%.*]] = and i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[R:%.*]] = zext i8 [[R1]] to i16
+; CHECK-NEXT:    ret i16 [[R]]
+;
+  %zx = zext i8 %x to i16
+  call void @use_i16(i16 %zx)
+  %zy = zext i8 %y to i16
+  %r = and i16 %zx, %zy
+  ret i16 %r
+}
+
 define i16 @or_zext_zext(i8 %x, i4 %y) {
 ; CHECK-LABEL: define {{[^@]+}}@or_zext_zext
 ; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i4 [[Y]] to i8
-; CHECK-NEXT:    [[TMP2:%.*]] = or i8 [[X]], [[TMP1]]
-; CHECK-NEXT:    [[R:%.*]] = zext i8 [[TMP2]] to i16
+; CHECK-NEXT:    [[R1:%.*]] = or i8 [[X]], [[TMP1]]
+; CHECK-NEXT:    [[R:%.*]] = zext i8 [[R1]] to i16
 ; CHECK-NEXT:    ret i16 [[R]]
 ;
   %zx = zext i8 %x to i16
@@ -4274,12 +4305,41 @@ define i16 @or_zext_zext(i8 %x, i4 %y) {
   ret i16 %r
 }
 
+define i16 @or_zext_zext_2(i8 %x, i8 %y) {
+; CHECK-LABEL: define {{[^@]+}}@or_zext_zext_2
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[R1:%.*]] = or i8 [[Y]], [[X]]
+; CHECK-NEXT:    [[R:%.*]] = zext i8 [[R1]] to i16
+; CHECK-NEXT:    ret i16 [[R]]
+;
+  %zx = zext i8 %x to i16
+  %zy = zext i8 %y to i16
+  %r = or i16 %zy, %zx
+  ret i16 %r
+}
+
+define i16 @or_zext_zext_2_use1(i8 %x, i8 %y) {
+; CHECK-LABEL: define {{[^@]+}}@or_zext_zext_2_use1
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[ZX:%.*]] = zext i8 [[X]] to i16
+; CHECK-NEXT:    call void @use_i16(i16 [[ZX]])
+; CHECK-NEXT:    [[R1:%.*]] = or i8 [[Y]], [[X]]
+; CHECK-NEXT:    [[R:%.*]] = zext i8 [[R1]] to i16
+; CHECK-NEXT:    ret i16 [[R]]
+;
+  %zx = zext i8 %x to i16
+  call void @use_i16(i16 %zx)
+  %zy = zext i8 %y to i16
+  %r = or i16 %zy, %zx
+  ret i16 %r
+}
+
 define <2 x i16> @xor_zext_zext(<2 x i8> %x, <2 x i4> %y) {
 ; CHECK-LABEL: define {{[^@]+}}@xor_zext_zext
 ; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i4> [[Y:%.*]]) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = zext <2 x i4> [[Y]] to <2 x i8>
-; CHECK-NEXT:    [[TMP2:%.*]] = xor <2 x i8> [[X]], [[TMP1]]
-; CHECK-NEXT:    [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
+; CHECK-NEXT:    [[R1:%.*]] = xor <2 x i8> [[X]], [[TMP1]]
+; CHECK-NEXT:    [[R:%.*]] = zext <2 x i8> [[R1]] to <2 x i16>
 ; CHECK-NEXT:    ret <2 x i16> [[R]]
 ;
   %zx = zext <2 x i8> %x to <2 x i16>
@@ -4288,12 +4348,41 @@ define <2 x i16> @xor_zext_zext(<2 x i8> %x, <2 x i4> %y) {
   ret <2 x i16> %r
 }
 
+define <2 x i16> @xor_zext_zext_2(<2 x i8> %x, <2 x i8> %y) {
+; CHECK-LABEL: define {{[^@]+}}@xor_zext_zext_2
+; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
+; CHECK-NEXT:    [[R1:%.*]] = xor <2 x i8> [[X]], [[Y]]
+; CHECK-NEXT:    [[R:%.*]] = zext <2 x i8> [[R1]] to <2 x i16>
+; CHECK-NEXT:    ret <2 x i16> [[R]]
+;
+  %zx = zext <2 x i8> %x to <2 x i16>
+  %zy = zext <2 x i8> %y to <2 x i16>
+  %r = xor <2 x i16> %zx, %zy
+  ret <2 x i16> %r
+}
+
+define <2 x i16> @xor_zext_zext_2_use1(<2 x i8> %x, <2 x i8> %y) {
+; CHECK-LABEL: define {{[^@]+}}@xor_zext_zext_2_use1
+; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
+; CHECK-NEXT:    [[ZX:%.*]] = zext <2 x i8> [[X]] to <2 x i16>
+; CHECK-NEXT:    call void @use_2xi16(<2 x i16> [[ZX]])
+; CHECK-NEXT:    [[R1:%.*]] = xor <2 x i8> [[X]], [[Y]]
+; CHECK-NEXT:    [[R:%.*]] = zext <2 x i8> [[R1]] to <2 x i16>
+; CHECK-NEXT:    ret <2 x i16> [[R]]
+;
+  %zx = zext <2 x i8> %x to <2 x i16>
+  call void @use_2xi16(<2 x i16> %zx)
+  %zy = zext <2 x i8> %y to <2 x i16>
+  %r = xor <2 x i16> %zx, %zy
+  ret <2 x i16> %r
+}
+
 define i16 @and_sext_sext(i8 %x, i4 %y) {
 ; CHECK-LABEL: define {{[^@]+}}@and_sext_sext
 ; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i4 [[Y]] to i8
-; CHECK-NEXT:    [[TMP2:%.*]] = and i8 [[X]], [[TMP1]]
-; CHECK-NEXT:    [[R:%.*]] = sext i8 [[TMP2]] to i16
+; CHECK-NEXT:    [[R1:%.*]] = and i8 [[X]], [[TMP1]]
+; CHECK-NEXT:    [[R:%.*]] = sext i8 [[R1]] to i16
 ; CHECK-NEXT:    ret i16 [[R]]
 ;
   %sx = sext i8 %x to i16
@@ -4302,12 +4391,41 @@ define i16 @and_sext_sext(i8 %x, i4 %y) {
   ret i16 %r
 }
 
+define i16 @and_sext_sext_2(i8 %x, i8 %y) {
+; CHECK-LABEL: define {{[^@]+}}@and_sext_sext_2
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[R1:%.*]] = and i8 [[Y]], [[X]]
+; CHECK-NEXT:    [[R:%.*]] = sext i8 [[R1]] to i16
+; CHECK-NEXT:    ret i16 [[R]]
+;
+  %sx = sext i8 %x to i16
+  %sy = sext i8 %y to i16
+  %r = and i16 %sy, %sx
+  ret i16 %r
+}
+
+define i16 @and_sext_sext_2_use1(i8 %x, i8 %y) {
+; CHECK-LABEL: define {{[^@]+}}@and_sext_sext_2_use1
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[SX:%.*]] = sext i8 [[X]] to i16
+; CHECK-NEXT:    call void @use_i16(i16 [[SX]])
+; CHECK-NEXT:    [[R1:%.*]] = and i8 [[Y]], [[X]]
+; CHECK-NEXT:    [[R:%.*]] = sext i8 [[R1]] to i16
+; CHECK-NEXT:    ret i16 [[R]]
+;
+  %sx = sext i8 %x to i16
+  call void @use_i16(i16 %sx)
+  %sy = sext i8 %y to i16
+  %r = and i16 %sy, %sx
+  ret i16 %r
+}
+
 define i16 @or_sext_sext(i8 %x, i4 %y) {
 ; CHECK-LABEL: define {{[^@]+}}@or_sext_sext
 ; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i4 [[Y]] to i8
-; CHECK-NEXT:    [[TMP2:%.*]] = or i8 [[X]], [[TMP1]]
-; CHECK-NEXT:    [[R:%.*]] = sext i8 [[TMP2]] to i16
+; CHECK-NEXT:    [[R1:%.*]] = or i8 [[X]], [[TMP1]]
+; CHECK-NEXT:    [[R:%.*]] = sext i8 [[R1]] to i16
 ; CHECK-NEXT:    ret i16 [[R]]
 ;
   %sx = sext i8 %x to i16
@@ -4316,12 +4434,41 @@ define i16 @or_sext_sext(i8 %x, i4 %y) {
   ret i16 %r
 }
 
+define i16 @or_sext_sext_2(i8 %x, i8 %y) {
+; CHECK-LABEL: define {{[^@]+}}@or_sext_sext_2
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[R1:%.*]] = or i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[R:%.*]] = sext i8 [[R1]] to i16
+; CHECK-NEXT:    ret i16 [[R]]
+;
+  %sx = sext i8 %x to i16
+  %sy = sext i8 %y to i16
+  %r = or i16 %sx, %sy
+  ret i16 %r
+}
+
+define i16 @or_sext_sext_2_use1(i8 %x, i8 %y) {
+; CHECK-LABEL: define {{[^@]+}}@or_sext_sext_2_use1
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[SX:%.*]] = sext i8 [[X]] to i16
+; CHECK-NEXT:    call void @use_i16(i16 [[SX]])
+; CHECK-NEXT:    [[R1:%.*]] = or i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[R:%.*]] = sext i8 [[R1]] to i16
+; CHECK-NEXT:    ret i16 [[R]]
+;
+  %sx = sext i8 %x to i16
+  call void @use_i16(i16 %sx)
+  %sy = sext i8 %y to i16
+  %r = or i16 %sx, %sy
+  ret i16 %r
+}
+
 define i16 @xor_sext_sext(i8 %x, i4 %y) {
 ; CHECK-LABEL: define {{[^@]+}}@xor_sext_sext
 ; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i4 [[Y]] to i8
-; CHECK-NEXT:    [[TMP2:%.*]] = xor i8 [[X]], [[TMP1]]
-; CHECK-NEXT:    [[R:%.*]] = sext i8 [[TMP2]] to i16
+; CHECK-NEXT:    [[R1:%.*]] = xor i8 [[X]], [[TMP1]]
+; CHECK-NEXT:    [[R:%.*]] = sext i8 [[R1]] to i16
 ; CHECK-NEXT:    ret i16 [[R]]
 ;
   %sx = sext i8 %x to i16
@@ -4330,6 +4477,35 @@ define i16 @xor_sext_sext(i8 %x, i4 %y) {
   ret i16 %r
 }
 
+define i16 @xor_sext_sext_2(i8 %x, i8 %y) {
+; CHECK-LABEL: define {{[^@]+}}@xor_sext_sext_2
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[R1:%.*]] = xor i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[R:%.*]] = sext i8 [[R1]] to i16
+; CHECK-NEXT:    ret i16 [[R]]
+;
+  %sx = sext i8 %x to i16
+  %sy = sext i8 %y to i16
+  %r = xor i16 %sx, %sy
+  ret i16 %r
+}
+
+define i16 @xor_sext_sext_2_use1(i8 %x, i8 %y) {
+; CHECK-LABEL: define {{[^@]+}}@xor_sext_sext_2_use1
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[SX:%.*]] = sext i8 [[X]] to i16
+; CHECK-NEXT:    call void @use_i16(i16 [[SX]])
+; CHECK-NEXT:    [[R1:%.*]] = xor i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[R:%.*]] = sext i8 [[R1]] to i16
+; CHECK-NEXT:    ret i16 [[R]]
+;
+  %sx = sext i8 %x to i16
+  call void @use_i16(i16 %sx)
+  %sy = sext i8 %y to i16
+  %r = xor i16 %sx, %sy
+  ret i16 %r
+}
+
 ; negative test - mismatched casts
 
 define i16 @and_zext_sext(i8 %x, i4 %y) {
@@ -4364,6 +4540,24 @@ define i32 @and_zext_zext_use1(i8 %x, i4 %y) {
   ret i32 %r
 }
 
+define i32 @and_zext_zext_use2(i8 %x, i8 %y) {
+; CHECK-LABEL: define {{[^@]+}}@and_zext_zext_use2
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[ZX:%.*]] = zext i8 [[X]] to i32
+; CHECK-NEXT:    call void @use(i32 [[ZX]])
+; CHECK-NEXT:    [[ZY:%.*]] = zext i8 [[Y]] to i32
+; CHECK-NEXT:    call void @use(i32 [[ZY]])
+; CHECK-NEXT:    [[R:%.*]] = and i32 [[ZX]], [[ZY]]
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %zx = zext i8 %x to i32
+  call void @use(i32 %zx)
+  %zy = zext i8 %y to i32
+  call void @use(i32 %zy)
+  %r = and i32 %zx, %zy
+  ret i32 %r
+}
+
 ; negative test - don't create an extra instruction
 
 define i32 @or_sext_sext_use1(i8 %x, i4 %y) {
@@ -4382,6 +4576,24 @@ define i32 @or_sext_sext_use1(i8 %x, i4 %y) {
   ret i32 %r
 }
 
+define i32 @or_sext_sext_use2(i8 %x, i8 %y) {
+; CHECK-LABEL: define {{[^@]+}}@or_sext_sext_use2
+; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT:    [[SX:%.*]] = sext i8 [[X]] to i32
+; CHECK-NEXT:    call void @use(i32 [[SX]])
+; CHECK-NEXT:    [[SY:%.*]] = sext i8 [[Y]] to i32
+; CHECK-NEXT:    call void @use(i32 [[SY]])
+; CHECK-NEXT:    [[R:%.*]] = or i32 [[SX]], [[SY]]
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %sx = sext i8 %x to i32
+  call void @use(i32 %sx)
+  %sy = sext i8 %y to i32
+  call void @use(i32 %sy)
+  %r = or i32 %sx, %sy
+  ret i32 %r
+}
+
 define i1 @PR56294(i8 %x) {
 ; CHECK-LABEL: define {{[^@]+}}@PR56294
 ; CHECK-SAME: (i8 [[X:%.*]]) {

@nikic nikic changed the title [RISCV] Refactor the code for folding logicop and sext/zext [InstCombine] Refactor the code for folding logicop and sext/zext Apr 24, 2025
Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@tclin914 tclin914 changed the title [InstCombine] Refactor the code for folding logicop and sext/zext [InstCombine] Refactor the code for folding logicop and sext/zext. NFC. Apr 24, 2025
@tclin914 tclin914 merged commit 462bf47 into llvm:main Apr 25, 2025
14 checks passed
@tclin914 tclin914 deleted the refactor-folding-logicop-cast branch April 25, 2025 02:59
@llvm-ci
Copy link
Collaborator

llvm-ci commented Apr 25, 2025

LLVM Buildbot has detected a new failure on builder sanitizer-aarch64-linux-bootstrap-asan running on sanitizer-buildbot8 while building llvm at step 2 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/24/builds/7734

Here is the relevant piece of the build log for the reference
Step 2 (annotate) failure: 'python ../sanitizer_buildbot/sanitizers/zorg/buildbot/builders/sanitizers/buildbot_selector.py' (failure)
...
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using lld-link: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/lld-link
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using ld64.lld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using wasm-ld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using ld.lld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/ld.lld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using lld-link: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/lld-link
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using ld64.lld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using wasm-ld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/main.py:72: note: The test suite configuration requested an individual test timeout of 0 seconds but a timeout of 900 seconds was requested on the command line. Forcing timeout to be 900 seconds.
-- Testing: 87997 tests, 72 workers --
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 
FAIL: LLVM :: ExecutionEngine/JITLink/x86-64/MachO_weak_references.s (53683 of 87997)
******************** TEST 'LLVM :: ExecutionEngine/JITLink/x86-64/MachO_weak_references.s' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
rm -rf /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp && mkdir -p /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp # RUN: at line 1
+ rm -rf /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp
+ mkdir -p /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp
/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj -o /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s # RUN: at line 2
+ /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj -o /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s
/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-jitlink -noexec -check-name=jitlink-check-bar-present -abs bar=0x1 -check=/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o # RUN: at line 3
+ /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-jitlink -noexec -check-name=jitlink-check-bar-present -abs bar=0x1 -check=/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o
/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-jitlink -noexec -check-name=jitlink-check-bar-absent -check=/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o # RUN: at line 4
+ /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-jitlink -noexec -check-name=jitlink-check-bar-absent -check=/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o

--

********************
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. 
Slowest Tests:
--------------------------------------------------------------------------
245.94s: Clang :: Driver/fsanitize.c
173.70s: Clang :: Preprocessor/riscv-target-features.c
168.95s: Clang :: OpenMP/target_defaultmap_codegen_01.cpp
147.93s: Clang :: OpenMP/target_update_codegen.cpp
140.87s: Clang :: Driver/arm-cortex-cpus-2.c
137.84s: Clang :: Driver/arm-cortex-cpus-1.c
129.01s: LLVM :: CodeGen/RISCV/attributes.ll
125.79s: Clang :: Preprocessor/arm-target-features.c
121.00s: Clang :: Preprocessor/aarch64-target-features.c
107.12s: LLVM :: CodeGen/AMDGPU/sched-group-barrier-pipeline-solver.mir
103.67s: Clang :: Preprocessor/predefined-arch-macros.c
92.94s: Clang :: Driver/clang_f_opts.c
92.70s: Clang :: Driver/linux-ld.c
83.64s: Clang :: Driver/x86-target-features.c
82.86s: Clang :: Driver/cl-options.c
82.03s: Clang :: OpenMP/target_data_codegen.cpp
76.41s: LLVM :: CodeGen/ARM/build-attributes.ll
Step 11 (stage2/asan check) failure: stage2/asan check (failure)
...
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using lld-link: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/lld-link
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using ld64.lld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using wasm-ld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using ld.lld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/ld.lld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using lld-link: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/lld-link
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using ld64.lld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:520: note: using wasm-ld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/main.py:72: note: The test suite configuration requested an individual test timeout of 0 seconds but a timeout of 900 seconds was requested on the command line. Forcing timeout to be 900 seconds.
-- Testing: 87997 tests, 72 workers --
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 
FAIL: LLVM :: ExecutionEngine/JITLink/x86-64/MachO_weak_references.s (53683 of 87997)
******************** TEST 'LLVM :: ExecutionEngine/JITLink/x86-64/MachO_weak_references.s' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
rm -rf /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp && mkdir -p /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp # RUN: at line 1
+ rm -rf /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp
+ mkdir -p /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp
/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj -o /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s # RUN: at line 2
+ /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj -o /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s
/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-jitlink -noexec -check-name=jitlink-check-bar-present -abs bar=0x1 -check=/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o # RUN: at line 3
+ /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-jitlink -noexec -check-name=jitlink-check-bar-present -abs bar=0x1 -check=/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o
/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-jitlink -noexec -check-name=jitlink-check-bar-absent -check=/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o # RUN: at line 4
+ /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-jitlink -noexec -check-name=jitlink-check-bar-absent -check=/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o

--

********************
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. 
Slowest Tests:
--------------------------------------------------------------------------
245.94s: Clang :: Driver/fsanitize.c
173.70s: Clang :: Preprocessor/riscv-target-features.c
168.95s: Clang :: OpenMP/target_defaultmap_codegen_01.cpp
147.93s: Clang :: OpenMP/target_update_codegen.cpp
140.87s: Clang :: Driver/arm-cortex-cpus-2.c
137.84s: Clang :: Driver/arm-cortex-cpus-1.c
129.01s: LLVM :: CodeGen/RISCV/attributes.ll
125.79s: Clang :: Preprocessor/arm-target-features.c
121.00s: Clang :: Preprocessor/aarch64-target-features.c
107.12s: LLVM :: CodeGen/AMDGPU/sched-group-barrier-pipeline-solver.mir
103.67s: Clang :: Preprocessor/predefined-arch-macros.c
92.94s: Clang :: Driver/clang_f_opts.c
92.70s: Clang :: Driver/linux-ld.c
83.64s: Clang :: Driver/x86-target-features.c
82.86s: Clang :: Driver/cl-options.c
82.03s: Clang :: OpenMP/target_data_codegen.cpp
76.41s: LLVM :: CodeGen/ARM/build-attributes.ll

IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…C. (llvm#137132)

This refactoring is for more easily adding the code to preserve disjoint
or in the PR llvm#136815.

Both casts must have one use for folding logicop and sext/zext when the
src type differ to avoid creating an extra instruction. If the src type
of casts are the same, only one of the casts needs to have one use. This
PR also adds more tests for the same src type.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…C. (llvm#137132)

This refactoring is for more easily adding the code to preserve disjoint
or in the PR llvm#136815.

Both casts must have one use for folding logicop and sext/zext when the
src type differ to avoid creating an extra instruction. If the src type
of casts are the same, only one of the casts needs to have one use. This
PR also adds more tests for the same src type.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…C. (llvm#137132)

This refactoring is for more easily adding the code to preserve disjoint
or in the PR llvm#136815.

Both casts must have one use for folding logicop and sext/zext when the
src type differ to avoid creating an extra instruction. If the src type
of casts are the same, only one of the casts needs to have one use. This
PR also adds more tests for the same src type.
Ankur-0429 pushed a commit to Ankur-0429/llvm-project that referenced this pull request May 9, 2025
…C. (llvm#137132)

This refactoring is for more easily adding the code to preserve disjoint
or in the PR llvm#136815.

Both casts must have one use for folding logicop and sext/zext when the
src type differ to avoid creating an extra instruction. If the src type
of casts are the same, only one of the casts needs to have one use. This
PR also adds more tests for the same src type.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:instcombine Covers the InstCombine, InstSimplify and AggressiveInstCombine passes llvm:transforms
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants