[llvm] [TargetLowering] Only freeze LHS and RHS if they are used multiple times in expandABD (PR #156193)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 31 02:51:40 PDT 2025


https://github.com/RKSimon updated https://github.com/llvm/llvm-project/pull/156193

>From 9441aa49a30761247adf9b93d33f80bb2bfee4cc Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Sat, 30 Aug 2025 13:43:13 -0400
Subject: [PATCH] [TargetLowering] Only freeze LHS and RHS if they are used
 multiple times

---
 .../CodeGen/SelectionDAG/TargetLowering.cpp   | 23 +++++++++++--------
 llvm/test/CodeGen/Thumb2/abds-crash.ll        | 12 +++++-----
 2 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 402a012e8e555..0d56f0d5ca114 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -9740,8 +9740,8 @@ SDValue TargetLowering::expandABS(SDNode *N, SelectionDAG &DAG,
 SDValue TargetLowering::expandABD(SDNode *N, SelectionDAG &DAG) const {
   SDLoc dl(N);
   EVT VT = N->getValueType(0);
-  SDValue LHS = DAG.getFreeze(N->getOperand(0));
-  SDValue RHS = DAG.getFreeze(N->getOperand(1));
+  SDValue LHS = N->getOperand(0);
+  SDValue RHS = N->getOperand(1);
   bool IsSigned = N->getOpcode() == ISD::ABDS;
 
   // abds(lhs, rhs) -> sub(smax(lhs,rhs), smin(lhs,rhs))
@@ -9749,34 +9749,37 @@ SDValue TargetLowering::expandABD(SDNode *N, SelectionDAG &DAG) const {
   unsigned MaxOpc = IsSigned ? ISD::SMAX : ISD::UMAX;
   unsigned MinOpc = IsSigned ? ISD::SMIN : ISD::UMIN;
   if (isOperationLegal(MaxOpc, VT) && isOperationLegal(MinOpc, VT)) {
+    LHS = DAG.getFreeze(LHS);
+    RHS = DAG.getFreeze(RHS);
     SDValue Max = DAG.getNode(MaxOpc, dl, VT, LHS, RHS);
     SDValue Min = DAG.getNode(MinOpc, dl, VT, LHS, RHS);
     return DAG.getNode(ISD::SUB, dl, VT, Max, Min);
   }
 
   // abdu(lhs, rhs) -> or(usubsat(lhs,rhs), usubsat(rhs,lhs))
-  if (!IsSigned && isOperationLegal(ISD::USUBSAT, VT))
+  if (!IsSigned && isOperationLegal(ISD::USUBSAT, VT)) {
+    LHS = DAG.getFreeze(LHS);
+    RHS = DAG.getFreeze(RHS);
     return DAG.getNode(ISD::OR, dl, VT,
                        DAG.getNode(ISD::USUBSAT, dl, VT, LHS, RHS),
                        DAG.getNode(ISD::USUBSAT, dl, VT, RHS, LHS));
+  }
 
   // If the subtract doesn't overflow then just use abs(sub())
-  // NOTE: don't use frozen operands for value tracking.
-  bool IsNonNegative = DAG.SignBitIsZero(N->getOperand(1)) &&
-                       DAG.SignBitIsZero(N->getOperand(0));
+  bool IsNonNegative = DAG.SignBitIsZero(LHS) && DAG.SignBitIsZero(RHS);
 
-  if (DAG.willNotOverflowSub(IsSigned || IsNonNegative, N->getOperand(0),
-                             N->getOperand(1)))
+  if (DAG.willNotOverflowSub(IsSigned || IsNonNegative, LHS, RHS))
     return DAG.getNode(ISD::ABS, dl, VT,
                        DAG.getNode(ISD::SUB, dl, VT, LHS, RHS));
 
-  if (DAG.willNotOverflowSub(IsSigned || IsNonNegative, N->getOperand(1),
-                             N->getOperand(0)))
+  if (DAG.willNotOverflowSub(IsSigned || IsNonNegative, RHS, LHS))
     return DAG.getNode(ISD::ABS, dl, VT,
                        DAG.getNode(ISD::SUB, dl, VT, RHS, LHS));
 
   EVT CCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
   ISD::CondCode CC = IsSigned ? ISD::CondCode::SETGT : ISD::CondCode::SETUGT;
+  LHS = DAG.getFreeze(LHS);
+  RHS = DAG.getFreeze(RHS);
   SDValue Cmp = DAG.getSetCC(dl, CCVT, LHS, RHS, CC);
 
   // Branchless expansion iff cmp result is allbits:
diff --git a/llvm/test/CodeGen/Thumb2/abds-crash.ll b/llvm/test/CodeGen/Thumb2/abds-crash.ll
index 52dda72dffa0e..2c872df178e97 100644
--- a/llvm/test/CodeGen/Thumb2/abds-crash.ll
+++ b/llvm/test/CodeGen/Thumb2/abds-crash.ll
@@ -9,13 +9,13 @@ define void @vp8_rd_pick_inter_mode() {
 ; CHECK-NEXT:    push {r4, lr}
 ; CHECK-NEXT:    movs r4, #0
 ; CHECK-NEXT:    ldr r0, [r0]
-; CHECK-NEXT:    ldr r1, [r4]
-; CHECK-NEXT:    movs r2, #180
-; CHECK-NEXT:    str r0, [r2]
-; CHECK-NEXT:    movs r2, #188
+; CHECK-NEXT:    ldr r2, [r4]
+; CHECK-NEXT:    movs r1, #180
+; CHECK-NEXT:    str r0, [r1]
+; CHECK-NEXT:    movs r1, #188
 ; CHECK-NEXT:    sxth r0, r0
-; CHECK-NEXT:    str r1, [r2]
-; CHECK-NEXT:    sxth r1, r1
+; CHECK-NEXT:    str r2, [r1]
+; CHECK-NEXT:    sxth r1, r2
 ; CHECK-NEXT:    subs r0, r0, r1
 ; CHECK-NEXT:    it mi
 ; CHECK-NEXT:    rsbmi r0, r0, #0



More information about the llvm-commits mailing list