[llvm] [MIPS]Remove unnecessary SLL instructions on MIPS64el (PR #109386)

via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 20 00:59:46 PDT 2024


https://github.com/anbbna created https://github.com/llvm/llvm-project/pull/109386

Optimize ((signext (xor (trunc X), imm)) to (xor (X, imm").

Fix https://github.com/llvm/llvm-project/issues/99783

>From 64cf138cabe5a33621a87f39d4787a2cf6935f58 Mon Sep 17 00:00:00 2001
From: anbb <beibei.an at oss.cipunited.com>
Date: Fri, 20 Sep 2024 03:52:49 -0400
Subject: [PATCH] [MIPS]Remove unnecessary SLL instructions on MIPS64el

Optimize ((signext (xor (trunc X), imm)) to (xor (X, imm").
---
 llvm/lib/Target/Mips/MipsISelLowering.cpp | 22 +++++++++++++++++++++-
 llvm/test/CodeGen/Mips/xor-and.ll         |  5 +----
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index 4345b8e66f6a0b..018fe52d9935e6 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -519,7 +519,8 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
   setOperationAction(ISD::TRAP, MVT::Other, Legal);
 
   setTargetDAGCombine({ISD::SDIVREM, ISD::UDIVREM, ISD::SELECT, ISD::AND,
-                       ISD::OR, ISD::ADD, ISD::SUB, ISD::AssertZext, ISD::SHL});
+                       ISD::OR, ISD::ADD, ISD::SUB, ISD::AssertZext, ISD::SHL
+                       ISD::SIGN_EXTEND});
 
   if (Subtarget.isGP64bit())
     setMaxAtomicSizeInBitsSupported(64);
@@ -1213,6 +1214,23 @@ static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
                      DAG.getConstant(SMSize, DL, MVT::i32));
 }
 
+static SDValue performSignExtendCombine(SDNode *N, SelectionDAG &DAG,
+                                    TargetLowering::DAGCombinerInfo &DCI,
+                                    const MipsSubtarget &Subtarget) {
+  SDValue N0 = N->getOperand(0);
+  EVT VT = N->getValueType(0);
+
+  // For MIPS64, xor instruction can use with 64 bit arithmetic.
+  // (sext (xor (trunc X), imm)) => (xor (X, imm"))
+  if (N0.getOpcode() == ISD::XOR &&
+      N0.getOperand(0).getOpcode() == ISD::TRUNCATE &&
+      N0.getOperand(1).getOpcode() == ISD::Constant) {
+      SDValue X0 = N0.getOperand(0).getOperand(0);
+      return DAG.getNode(ISD::XOR, SDLoc(N0), VT,
+                         X0, DAG.getTargetConstant(-1, SDLoc(N0), VT));
+  }
+}
+
 SDValue  MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
   const {
   SelectionDAG &DAG = DCI.DAG;
@@ -1238,6 +1256,8 @@ SDValue  MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
     return performSHLCombine(N, DAG, DCI, Subtarget);
   case ISD::SUB:
     return performSUBCombine(N, DAG, DCI, Subtarget);
+  case ISD::SIGN_EXTEND:
+    return performSignExtendCombine(N, DAG, DCI, Subtarget);
   }
 
   return SDValue();
diff --git a/llvm/test/CodeGen/Mips/xor-and.ll b/llvm/test/CodeGen/Mips/xor-and.ll
index 3a173baf205d3a..e08ca21a0c05de 100644
--- a/llvm/test/CodeGen/Mips/xor-and.ll
+++ b/llvm/test/CodeGen/Mips/xor-and.ll
@@ -1,14 +1,11 @@
 ; RUN: llc -O3 -mcpu=mips64r6 -mtriple=mips64el-unknown-linux-gnuabi64 < %s -o - | FileCheck %s
 
-; This test shows the unoptimized result with unnecessary SLLs.
 define noundef signext i32 @xor_and(i32 noundef signext %a, i32 noundef signext %b) local_unnamed_addr {
 ; CHECK-LABEL: xor_and:
 ; CHECK:       # %bb.0: # %entry
 ; CHECK-NEXT:    and $1, $5, $4
-; CHECK-NEXT:    sll $1, $1, 0
-; CHECK-NEXT:    not $1, $1
 ; CHECK-NEXT:    jr $ra
-; CHECK-NEXT:    sll $2, $1, 0
+; CHECK-NEXT:    xor $2, $1, -1
 
 entry:
   %0 = and i32 %b, %a



More information about the llvm-commits mailing list