[llvm] [SelectionDAG] Improve isOrEquivalentToAdd (PR #82767)

via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 23 21:21:12 PST 2024


https://github.com/heiher updated https://github.com/llvm/llvm-project/pull/82767

>From 7242beb0d7ce90eaf1c2af91478bfbea87e10829 Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Fri, 23 Feb 2024 20:41:15 +0800
Subject: [PATCH 1/2] [SelectionDAG] Improve isOrEquivalentToAdd

`SelectionDAGISel::isOrEquivalentToAdd` can only test operands that are
directly based on the stack frame. The improvement in this commit is to
add a call to `SelectionDAG::haveNoCommonBitsSet` for testing, which
helps optimize the code generation for `load (or base, imm)`.
---
 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 2 +-
 llvm/test/CodeGen/LoongArch/intrinsic-memcpy.ll    | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 9b5ab4267b80e9..0cf9a02af35c49 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -4214,7 +4214,7 @@ bool SelectionDAGISel::isOrEquivalentToAdd(const SDNode *N) const {
     // the alignment, then this or is really an add.
     return (Off >= 0) && (((A.value() - 1) & Off) == unsigned(Off));
   }
-  return false;
+  return CurDAG->haveNoCommonBitsSet(N->getOperand(0), N->getOperand(1));
 }
 
 void SelectionDAGISel::CannotYetSelect(SDNode *N) {
diff --git a/llvm/test/CodeGen/LoongArch/intrinsic-memcpy.ll b/llvm/test/CodeGen/LoongArch/intrinsic-memcpy.ll
index 09453004dcef74..ff845cb1f3dbd9 100644
--- a/llvm/test/CodeGen/LoongArch/intrinsic-memcpy.ll
+++ b/llvm/test/CodeGen/LoongArch/intrinsic-memcpy.ll
@@ -22,8 +22,7 @@ define void @box(ptr noalias nocapture noundef writeonly sret(%Box) align 16 der
 ; CHECK-NEXT:    st.d $a1, $a0, 24
 ; CHECK-NEXT:    ld.d $a1, $a3, 16
 ; CHECK-NEXT:    st.d $a1, $a0, 16
-; CHECK-NEXT:    ori $a1, $a3, 8
-; CHECK-NEXT:    ld.d $a1, $a1, 0
+; CHECK-NEXT:    ld.d $a1, $a3, 8
 ; CHECK-NEXT:    st.d $a1, $a0, 8
 ; CHECK-NEXT:    addi.d $sp, $sp, 96
 ; CHECK-NEXT:    ret

>From 16098470af822c936047deaf385ee684d349333a Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Sat, 24 Feb 2024 13:15:38 +0800
Subject: [PATCH 2/2] [LoongArch] Improve pattern matching for AddLike
 predicate

This commit updates the pattern matching logic for the `AddLike` predicate in
`LoongArchInstrInfo.td` to use the `isBaseWithConstantOffset` function provided
by `CurDAG`. This optimization aims to improve the effciency of pattern matching
by identifying cases where the operation can be represented as a base address
plus a constant offset, which can lead to more efficient code generation.
---
 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 2 +-
 llvm/lib/Target/LoongArch/LoongArchInstrInfo.td    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 0cf9a02af35c49..9b5ab4267b80e9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -4214,7 +4214,7 @@ bool SelectionDAGISel::isOrEquivalentToAdd(const SDNode *N) const {
     // the alignment, then this or is really an add.
     return (Off >= 0) && (((A.value() - 1) & Off) == unsigned(Off));
   }
-  return CurDAG->haveNoCommonBitsSet(N->getOperand(0), N->getOperand(1));
+  return false;
 }
 
 void SelectionDAGISel::CannotYetSelect(SDNode *N) {
diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
index ae73a8ac74c718..fcfff08d1a9f54 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -1048,7 +1048,7 @@ class PatGprImm_32<SDPatternOperator OpNode, LAInst Inst, Operand ImmOpnd>
 /// Predicates
 def AddLike: PatFrags<(ops node:$A, node:$B),
                       [(add node:$A, node:$B), (or node:$A, node:$B)], [{
-    return N->getOpcode() == ISD::ADD || isOrEquivalentToAdd(N);
+    return CurDAG->isBaseWithConstantOffset(SDValue(N, 0));
 }]>;
 
 /// Simple arithmetic operations



More information about the llvm-commits mailing list