Skip to content

[DAG] Fold (and X, (add (not Y), Z)) -> (and X, (not (sub Y, Z))). #141476

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 9 commits into from
Jun 16, 2025

Conversation

simonzgx
Copy link
Contributor

@simonzgx simonzgx commented May 26, 2025

Fixes #140639

@llvmbot llvmbot added the llvm:SelectionDAG SelectionDAGISel as well label May 26, 2025
@simonzgx simonzgx marked this pull request as draft May 26, 2025 11:19
@llvmbot
Copy link
Member

llvmbot commented May 26, 2025

@llvm/pr-subscribers-backend-x86
@llvm/pr-subscribers-backend-aarch64
@llvm/pr-subscribers-backend-loongarch

@llvm/pr-subscribers-llvm-selectiondag

Author: Xu Zhang (simonzgx)

Changes

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

1 Files Affected:

  • (modified) llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (+7)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index efaa8bd4a7950..31fbab23e4fcf 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -7528,6 +7528,13 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
       return DAG.getNode(ISD::AND, DL, VT, X,
                          DAG.getNOT(DL, DAG.getNode(Opc, DL, VT, Y, Z), VT));
 
+  // a bitwiseop (~b + c) -> a bitwiseop ~(b - c).
+  // Fold (and X, (add (not Y), Z)) -> (and X, (not (sub Y, Z)))
+  if (sd_match(N, m_And(m_Value(X), m_Add(m_Value(NotY), m_Value(Z)))) &&
+      sd_match(NotY, m_Not(m_Value(Y))) &&
+      (TLI.hasAndNot(SDValue(N, 0)) || NotY->hasOneUse())) {
+		return DAG.getNode(ISD::AND, DL, VT, X, DAG.getNOT(DL, DAG.getNode(ISD::SUB, DL, VT, Y, Z), VT));
+  }
   // Fold (and (srl X, C), 1) -> (srl X, BW-1) for signbit extraction
   // If we are shifting down an extended sign bit, see if we can simplify
   // this to shifting the MSB directly to expose further simplifications.

Copy link

github-actions bot commented May 26, 2025

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

@jayfoad
Copy link
Contributor

jayfoad commented May 27, 2025

As well as ~y+z --> ~(y-z) you can also do ~y-z --> ~(y+z) right?

@RKSimon RKSimon requested review from jayfoad, arsenm and RKSimon May 27, 2025 11:11
Copy link
Contributor

@arsenm arsenm left a comment

Choose a reason for hiding this comment

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

Needs tests

@simonzgx
Copy link
Contributor Author

Needs tests

Yes, there are some failed UT that need fixing and some new ones to add. I'm still working on both and will submit soon.

@simonzgx simonzgx changed the title [WIP] Fold (bitwiseop X, (add (not Y), Z)) -> (bitwiseop X, (not (sub Y, Z))). [DAG] Fold (bitwiseop X, (add (not Y), Z)) -> (bitwiseop X, (not (sub Y, Z))). May 29, 2025
@simonzgx simonzgx marked this pull request as ready for review May 29, 2025 11:10
@simonzgx simonzgx requested review from arsenm and RKSimon May 29, 2025 11:11
@simonzgx simonzgx changed the title [DAG] Fold (bitwiseop X, (add (not Y), Z)) -> (bitwiseop X, (not (sub Y, Z))). [DAG] Fold (and X, (add (not Y), Z)) -> (and X, (not (sub Y, Z))). Jun 2, 2025
@simonzgx
Copy link
Contributor Author

pin


if (sd_match(N, m_BitwiseLogic(m_Value(X),
m_Sub(m_AllOf(m_Value(Y), m_Not(m_Value(Y)),
m_OneUse(m_Not(m_Value(Y)))),
Copy link
Collaborator

Choose a reason for hiding this comment

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

The m_OneUse isn't doing anything as the previous pattern is matching all m_Not cases

Copy link
Collaborator

@RKSimon RKSimon left a comment

Choose a reason for hiding this comment

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

Please can regenerate the failing test files:
LLVM :: CodeGen/LoongArch/ctlz-cttz-ctpop.ll
LLVM :: CodeGen/X86/vector-lzcnt-128.ll

Copy link
Collaborator

@RKSimon RKSimon left a comment

Choose a reason for hiding this comment

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

LGTM - cheers!

@RKSimon RKSimon merged commit 7c25db3 into llvm:main Jun 16, 2025
7 checks passed
fschlimb pushed a commit to fschlimb/llvm-project that referenced this pull request Jun 18, 2025
…lvm#141476)

Fixes llvm#140639

---------

Co-authored-by: Simon Pilgrim <llvm-dev@redking.me.uk>
akuhlens pushed a commit to akuhlens/llvm-project that referenced this pull request Jun 24, 2025
…lvm#141476)

Fixes llvm#140639

---------

Co-authored-by: Simon Pilgrim <llvm-dev@redking.me.uk>
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.

a & ~(a - b) optimizes to a & (~a + b) even though most targets have an ANDN instruction
5 participants