[llvm] [DAGCombiner] Fold sext_in_reg when adding sign bit to an already extended value. (PR #214848)
Usman Nadeem via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 7 13:49:26 PDT 2026
https://github.com/UsmanNadeem created https://github.com/llvm/llvm-project/pull/214848
Proof: https://alive2.llvm.org/ce/z/HEaaA5
>From 2e1da7d788ac4a7d11874741aaee0b21e7e3d552 Mon Sep 17 00:00:00 2001
From: Usman Nadeem <mnadeem at qti.qualcomm.com>
Date: Fri, 7 Aug 2026 13:45:14 -0700
Subject: [PATCH] [DAGCombiner] Fold sext_in_reg when adding sign bit to an
already extended value.
Change-Id: Icbd1c7b02734a198cb5eb653a3912b09a6a3140e
Proof: https://alive2.llvm.org/ce/z/HEaaA5
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 19 +++++++++++++++++++
llvm/test/CodeGen/ARM/sdiv-pow2-arm-size.ll | 1 -
llvm/test/CodeGen/ARM/sdiv-pow2-thumb-size.ll | 4 ----
llvm/test/CodeGen/RISCV/sdiv-pow2-cmov.ll | 4 ++--
4 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index f5620743d6ed1..6973bcdc9d259 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -17223,6 +17223,25 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
if (DAG.MaskedValueIsZero(N0, APInt::getOneBitSet(VTBits, ExtVTBits - 1)))
return DAG.getZeroExtendInReg(N0, DL, ExtVT);
+ // fold (sext_in_reg add(x, sign_bit_of(x))) -> add(x, sign_bit_of(x))
+ // if we are not extending beyond the original extension type of x.
+ {
+ SDValue AddOp;
+ uint64_t BitNo;
+ APInt BitMask;
+ if (sd_match(N0,
+ m_c_BinOp(ISD::ADD, m_Value(AddOp),
+ m_Srl(m_And(m_Deferred(AddOp), m_ConstInt(BitMask)),
+ m_ConstInt(BitNo)))) &&
+ BitMask == APInt::getOneBitSet(VTBits, BitNo)) {
+ unsigned SignBits = DAG.ComputeNumSignBits(AddOp);
+ unsigned NonSignBits = VTBits - DAG.ComputeNumSignBits(AddOp);
+ unsigned ExtendedBits = VTBits - ExtVTBits;
+ if (BitNo >= NonSignBits && ExtendedBits < SignBits)
+ return N0;
+ }
+ }
+
// fold operands of sext_in_reg based on knowledge that the top bits are not
// demanded.
if (SimplifyDemandedBits(SDValue(N, 0)))
diff --git a/llvm/test/CodeGen/ARM/sdiv-pow2-arm-size.ll b/llvm/test/CodeGen/ARM/sdiv-pow2-arm-size.ll
index 53bc7f603bde1..e7490803924d3 100644
--- a/llvm/test/CodeGen/ARM/sdiv-pow2-arm-size.ll
+++ b/llvm/test/CodeGen/ARM/sdiv-pow2-arm-size.ll
@@ -30,7 +30,6 @@ define dso_local signext i16 @f0(i16 signext %F) local_unnamed_addr #0 {
; NODIV: @ %bb.0: @ %entry
; NODIV-NEXT: uxth r1, r0
; NODIV-NEXT: add r0, r0, r1, lsr #15
-; NODIV-NEXT: sxth r0, r0
; NODIV-NEXT: asr r0, r0, #1
; NODIV-NEXT: bx lr
diff --git a/llvm/test/CodeGen/ARM/sdiv-pow2-thumb-size.ll b/llvm/test/CodeGen/ARM/sdiv-pow2-thumb-size.ll
index cfd37bd3b86c0..819c14823a8b6 100644
--- a/llvm/test/CodeGen/ARM/sdiv-pow2-thumb-size.ll
+++ b/llvm/test/CodeGen/ARM/sdiv-pow2-thumb-size.ll
@@ -26,7 +26,6 @@ define dso_local signext i16 @f0(i16 signext %F) local_unnamed_addr #0 {
; V6M-NEXT: uxth r1, r0
; V6M-NEXT: lsrs r1, r1, #15
; V6M-NEXT: adds r0, r0, r1
-; V6M-NEXT: sxth r0, r0
; V6M-NEXT: asrs r0, r0, #1
; V6M-NEXT: bx lr
@@ -117,7 +116,6 @@ define dso_local signext i16 @f4(i16 signext %F) {
; T2: @ %bb.0: @ %entry
; T2-NEXT: uxth r1, r0
; T2-NEXT: add.w r0, r0, r1, lsr #15
-; T2-NEXT: sxth r0, r0
; T2-NEXT: asrs r0, r0, #1
; T2-NEXT: bx lr
;
@@ -126,7 +124,6 @@ define dso_local signext i16 @f4(i16 signext %F) {
; T1-NEXT: uxth r1, r0
; T1-NEXT: lsrs r1, r1, #15
; T1-NEXT: adds r0, r0, r1
-; T1-NEXT: sxth r0, r0
; T1-NEXT: asrs r0, r0, #1
; T1-NEXT: bx lr
;
@@ -135,7 +132,6 @@ define dso_local signext i16 @f4(i16 signext %F) {
; V6M-NEXT: uxth r1, r0
; V6M-NEXT: lsrs r1, r1, #15
; V6M-NEXT: adds r0, r0, r1
-; V6M-NEXT: sxth r0, r0
; V6M-NEXT: asrs r0, r0, #1
; V6M-NEXT: bx lr
diff --git a/llvm/test/CodeGen/RISCV/sdiv-pow2-cmov.ll b/llvm/test/CodeGen/RISCV/sdiv-pow2-cmov.ll
index f7dda82885678..7bbc9a55834f2 100644
--- a/llvm/test/CodeGen/RISCV/sdiv-pow2-cmov.ll
+++ b/llvm/test/CodeGen/RISCV/sdiv-pow2-cmov.ll
@@ -9,7 +9,7 @@ define signext i32 @sdiv2_32(i32 signext %0) {
; NOSFB: # %bb.0:
; NOSFB-NEXT: srliw a1, a0, 31
; NOSFB-NEXT: add a0, a0, a1
-; NOSFB-NEXT: sraiw a0, a0, 1
+; NOSFB-NEXT: srai a0, a0, 1
; NOSFB-NEXT: ret
;
; SFB-LABEL: sdiv2_32:
@@ -29,7 +29,7 @@ define signext i32 @sdivneg2_32(i32 signext %0) {
; NOSFB: # %bb.0:
; NOSFB-NEXT: srliw a1, a0, 31
; NOSFB-NEXT: add a0, a0, a1
-; NOSFB-NEXT: sraiw a0, a0, 1
+; NOSFB-NEXT: srai a0, a0, 1
; NOSFB-NEXT: neg a0, a0
; NOSFB-NEXT: ret
;
More information about the llvm-commits
mailing list