[llvm] [TargetLowering][X86] Directly emit FSHR from expandDIVREMByConstant when Legal. (PR #186863)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 16 16:01:38 PDT 2026


https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/186863

>From 74a1ec606d4b0019e347f5618682ac3b3c970f13 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 16 Mar 2026 12:21:28 -0700
Subject: [PATCH 1/2] [TargetLowering][X86] Directly emit FSHR from
 expandDIVREMByConstant when Legal.

---
 llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 16 ++++++++++------
 llvm/test/CodeGen/X86/divide-by-constant.ll      |  6 +++---
 llvm/test/CodeGen/X86/divmod128.ll               |  8 ++++----
 3 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 5748ef89aef4e..d3bcf7b985f36 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -8201,12 +8201,16 @@ bool TargetLowering::expandDIVREMByConstant(SDNode *N,
                                  DAG.getConstant(Mask, dl, HiLoVT));
       }
 
-      LL = DAG.getNode(
-          ISD::OR, dl, HiLoVT,
-          DAG.getNode(ISD::SRL, dl, HiLoVT, LL,
-                      DAG.getShiftAmountConstant(TrailingZeros, HiLoVT, dl)),
-          DAG.getNode(ISD::SHL, dl, HiLoVT, LH,
-                      DAG.getShiftAmountConstant(HBitWidth - TrailingZeros,
+      if (isOperationLegal(ISD::FSHR, HiLoVT))
+        LL = DAG.getNode(ISD::FSHR, dl, HiLoVT, LH, LL,
+                         DAG.getShiftAmountConstant(TrailingZeros, HiLoVT, dl));
+      else
+        LL = DAG.getNode(
+            ISD::OR, dl, HiLoVT,
+            DAG.getNode(ISD::SRL, dl, HiLoVT, LL,
+                        DAG.getShiftAmountConstant(TrailingZeros, HiLoVT, dl)),
+            DAG.getNode(ISD::SHL, dl, HiLoVT, LH,
+                        DAG.getShiftAmountConstant(HBitWidth - TrailingZeros,
                                                  HiLoVT, dl)));
       LH = DAG.getNode(ISD::SRL, dl, HiLoVT, LH,
                        DAG.getShiftAmountConstant(TrailingZeros, HiLoVT, dl));
diff --git a/llvm/test/CodeGen/X86/divide-by-constant.ll b/llvm/test/CodeGen/X86/divide-by-constant.ll
index ac78136b9d8ea..f15697aaf2df2 100644
--- a/llvm/test/CodeGen/X86/divide-by-constant.ll
+++ b/llvm/test/CodeGen/X86/divide-by-constant.ll
@@ -730,9 +730,9 @@ define i64 @urem_i64_12(i64 %x) nounwind {
 ; X86-NEXT:    pushl %esi
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, %eax
-; X86-NEXT:    shrl $2, %eax
-; X86-NEXT:    shldl $30, %esi, %ecx
+; X86-NEXT:    movl %esi, %eax
+; X86-NEXT:    shrdl $2, %ecx, %eax
+; X86-NEXT:    shrl $2, %ecx
 ; X86-NEXT:    addl %eax, %ecx
 ; X86-NEXT:    adcl $0, %ecx
 ; X86-NEXT:    movl $-1431655765, %edx # imm = 0xAAAAAAAB
diff --git a/llvm/test/CodeGen/X86/divmod128.ll b/llvm/test/CodeGen/X86/divmod128.ll
index 3796dd796eaf9..af37be791d27f 100644
--- a/llvm/test/CodeGen/X86/divmod128.ll
+++ b/llvm/test/CodeGen/X86/divmod128.ll
@@ -425,8 +425,8 @@ entry:
 define i128 @urem_i128_12(i128 %x) nounwind {
 ; X86-64-LABEL: urem_i128_12:
 ; X86-64:       # %bb.0: # %entry
-; X86-64-NEXT:    movq %rsi, %rcx
-; X86-64-NEXT:    shldq $62, %rdi, %rcx
+; X86-64-NEXT:    movq %rdi, %rcx
+; X86-64-NEXT:    shrdq $2, %rsi, %rcx
 ; X86-64-NEXT:    shrq $2, %rsi
 ; X86-64-NEXT:    addq %rsi, %rcx
 ; X86-64-NEXT:    adcq $0, %rcx
@@ -443,8 +443,8 @@ define i128 @urem_i128_12(i128 %x) nounwind {
 ;
 ; WIN64-LABEL: urem_i128_12:
 ; WIN64:       # %bb.0: # %entry
-; WIN64-NEXT:    movq %rdx, %r8
-; WIN64-NEXT:    shldq $62, %rcx, %r8
+; WIN64-NEXT:    movq %rcx, %r8
+; WIN64-NEXT:    shrdq $2, %rdx, %r8
 ; WIN64-NEXT:    shrq $2, %rdx
 ; WIN64-NEXT:    addq %rdx, %r8
 ; WIN64-NEXT:    adcq $0, %r8

>From 33a4dfbda62ef04f687e4c4188ce3b4e7d7013d5 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 16 Mar 2026 16:01:20 -0700
Subject: [PATCH 2/2] fixup! clang-format

---
 llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index d3bcf7b985f36..aa76fae674774 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -8211,7 +8211,7 @@ bool TargetLowering::expandDIVREMByConstant(SDNode *N,
                         DAG.getShiftAmountConstant(TrailingZeros, HiLoVT, dl)),
             DAG.getNode(ISD::SHL, dl, HiLoVT, LH,
                         DAG.getShiftAmountConstant(HBitWidth - TrailingZeros,
-                                                 HiLoVT, dl)));
+                                                   HiLoVT, dl)));
       LH = DAG.getNode(ISD::SRL, dl, HiLoVT, LH,
                        DAG.getShiftAmountConstant(TrailingZeros, HiLoVT, dl));
     }



More information about the llvm-commits mailing list