Skip to content
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

[InstCombine] simplify (X * C0) / (X * C1) into C0 / C1. #73204

Merged
merged 2 commits into from
Dec 13, 2023
Merged

Conversation

Z572
Copy link
Contributor

@Z572 Z572 commented Nov 23, 2023

@llvmbot
Copy link
Collaborator

llvmbot commented Nov 23, 2023

@llvm/pr-subscribers-llvm-transforms

Author: None (Z572)

Changes

fix #72114
proof: https://alive2.llvm.org/ce/z/IIEKgf


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

2 Files Affected:

  • (modified) llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (+12)
  • (modified) llvm/test/Transforms/InstCombine/div.ll (+123)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 40156726c7038b9..abbef95b434119b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -1207,6 +1207,18 @@ Instruction *InstCombinerImpl::commonIDivTransforms(BinaryOperator &I) {
     }
   }
 
+  // (X*C0)/(X*C1) --> C0/C1
+  Constant *C0,*C1;
+  if (match(Op0, m_c_Mul(m_Value(X), m_Constant(C0))) &&
+      match(Op1, m_c_Mul(m_Specific(X), m_Constant(C1)))) {
+    auto OB0HasNSW=cast<OverflowingBinaryOperator>(Op0)->hasNoSignedWrap();
+    auto OB0HasNUW = cast<OverflowingBinaryOperator>(Op0)->hasNoUnsignedWrap();
+    if ((IsSigned && OB0HasNSW) || (!IsSigned && OB0HasNUW)) {
+      replaceOperand(I, 0, C0);
+      replaceOperand(I, 1, C1);
+      return &I;
+    };
+  }
   return nullptr;
 }
 
diff --git a/llvm/test/Transforms/InstCombine/div.ll b/llvm/test/Transforms/InstCombine/div.ll
index cd17d10d0e1de07..4af884e002da8dd 100644
--- a/llvm/test/Transforms/InstCombine/div.ll
+++ b/llvm/test/Transforms/InstCombine/div.ll
@@ -1432,6 +1432,129 @@ define <2 x i8> @sdiv_sdiv_mul_nsw(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
   ret <2 x i8> %r
 }
 
+; (X * C0) / (X * C1) --> C0 / C1
+define i8 @sdiv_mul_nsw_mul(i8 %x,i8 %y,i8 %z) {
+; CHECK-LABEL: @sdiv_mul_nsw_mul(
+; CHECK-NEXT:    [[ADD4:%.*]] = mul i8 [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[ADD5:%.*]] = mul nsw i8 [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i8 [[ADD5]], [[ADD4]]
+; CHECK-NEXT:    ret i8 [[DIV]]
+;
+  %add4 = mul i8 %x, %z
+  %add5 = mul nsw i8 %x, %y
+  %div = sdiv i8 %add5, %add4
+  ret i8 %div
+}
+
+define i8 @sdiv_mul_nsw_mul_nsw(i8 %x,i8 %y,i8 %z) {
+; CHECK-LABEL: @sdiv_mul_nsw_mul_nsw(
+; CHECK-NEXT:    [[ADD4:%.*]] = mul nsw i8 [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[ADD5:%.*]] = mul nsw i8 [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i8 [[ADD5]], [[ADD4]]
+; CHECK-NEXT:    ret i8 [[DIV]]
+;
+  %add4 = mul nsw i8 %x, %z
+  %add5 = mul nsw i8 %x, %y
+  %div = sdiv i8 %add5, %add4
+  ret i8 %div
+}
+
+define i8 @sdiv_mul_mul_nsw(i8 %x,i8 %y,i8 %z) {
+; CHECK-LABEL: @sdiv_mul_mul_nsw(
+; CHECK-NEXT:    [[ADD4:%.*]] = mul nsw i8 [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[ADD5:%.*]] = mul i8 [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i8 [[ADD5]], [[ADD4]]
+; CHECK-NEXT:    ret i8 [[DIV]]
+;
+  %add4 = mul nsw i8 %x, %z
+  %add5 = mul i8 %x, %y
+  %div = sdiv i8 %add5, %add4
+  ret i8 %div
+}
+
+define i8 @sdiv_mul_mul(i8 %x,i8 %y,i8 %z) {
+; CHECK-LABEL: @sdiv_mul_mul(
+; CHECK-NEXT:    [[ADD4:%.*]] = mul i8 [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[ADD5:%.*]] = mul i8 [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i8 [[ADD5]], [[ADD4]]
+; CHECK-NEXT:    ret i8 [[DIV]]
+;
+  %add4 = mul i8 %x, %z
+  %add5 = mul i8 %x, %y
+  %div = sdiv i8 %add5, %add4
+  ret i8 %div
+}
+
+define i8 @udiv_mul_mul(i8 %x,i8 %y,i8 %z) {
+; CHECK-LABEL: @udiv_mul_mul(
+; CHECK-NEXT:    [[ADD4:%.*]] = mul i8 [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[ADD5:%.*]] = mul i8 [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[DIV:%.*]] = udiv i8 [[ADD5]], [[ADD4]]
+; CHECK-NEXT:    ret i8 [[DIV]]
+;
+  %add4 = mul i8 %x, %z
+  %add5 = mul i8 %x, %y
+  %div = udiv i8 %add5, %add4
+  ret i8 %div
+}
+
+define i8 @udiv_mul_nuw_mul_nuw(i8 %x,i8 %y,i8 %z) {
+; CHECK-LABEL: @udiv_mul_nuw_mul_nuw(
+; CHECK-NEXT:    [[DIV:%.*]] = udiv i8 [[Y:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    ret i8 [[DIV]]
+;
+  %add4 = mul nuw i8 %x, %z
+  %add5 = mul nuw i8 %x, %y
+  %div = udiv i8 %add5, %add4
+  ret i8 %div
+}
+
+define i8 @udiv_mul_mul_nuw(i8 %x,i8 %y,i8 %z) {
+; CHECK-LABEL: @udiv_mul_mul_nuw(
+; CHECK-NEXT:    [[ADD4:%.*]] = mul nuw i8 [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[ADD5:%.*]] = mul i8 [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[DIV:%.*]] = udiv i8 [[ADD5]], [[ADD4]]
+; CHECK-NEXT:    ret i8 [[DIV]]
+;
+  %add4 = mul nuw i8 %x, %z
+  %add5 = mul i8 %x, %y
+  %div = udiv i8 %add5, %add4
+  ret i8 %div
+}
+
+define i8 @udiv_mul_nuw_mul(i8 %x,i8 %y,i8 %z) {
+; CHECK-LABEL: @udiv_mul_nuw_mul(
+; CHECK-NEXT:    [[ADD4:%.*]] = mul i8 [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[ADD5:%.*]] = mul nuw i8 [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[DIV:%.*]] = udiv i8 [[ADD5]], [[ADD4]]
+; CHECK-NEXT:    ret i8 [[DIV]]
+;
+  %add4 = mul i8 %x, %z
+  %add5 = mul nuw i8 %x, %y
+  %div = udiv i8 %add5, %add4
+  ret i8 %div
+}
+
+define i8 @sdiv_mul_nsw_constant_mul_constant(i8 %a) {
+; CHECK-LABEL: @sdiv_mul_nsw_constant_mul_constant(
+; CHECK-NEXT:    ret i8 3
+;
+  %add4 = mul i8 %a, 6
+  %add5 = mul nsw i8 %a, 18
+  %div = sdiv i8 %add5, %add4
+  ret i8 %div
+}
+
+define i8 @udiv_mul_nuw_constant_mul_constant(i8 %a) {
+; CHECK-LABEL: @udiv_mul_nuw_constant_mul_constant(
+; CHECK-NEXT:    ret i8 2
+;
+  %add4 = mul i8 %a, 6
+  %add5 = mul nuw i8 %a, 12
+  %div = udiv i8 %add5, %add4
+  ret i8 %div
+}
+
 define i32 @sdiv_sub1(i32 %arg) {
 ; CHECK-LABEL: @sdiv_sub1(
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[ARG:%.*]], -2147483648

Copy link

github-actions bot commented Nov 23, 2023

:white_check_mark: With the latest revision this PR passed the C/C++ code formatter.

@Z572 Z572 force-pushed the patch-6 branch 2 times, most recently from 4767782 to 6a4b736 Compare November 23, 2023 04:10
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Outdated Show resolved Hide resolved
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Outdated Show resolved Hide resolved
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Outdated Show resolved Hide resolved
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Outdated Show resolved Hide resolved
llvm/test/Transforms/InstCombine/div.ll Outdated Show resolved Hide resolved
Copy link
Member

@dtcxzyw dtcxzyw left a comment

Choose a reason for hiding this comment

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

LGTM. Please wait for additional approval from other reviewers.

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

@Z572 Z572 merged commit 1c49419 into llvm:main Dec 13, 2023
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[InstCombine] (m+m)/(m) is not optimized when m=a+a+a, but it is for m=a+a
5 participants