[llvm] [DAG] Fold urem(urem(A, BCst), Op1Cst) -> urem(A, Op1Cst) (PR #159517)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 18 02:16:18 PDT 2025


https://github.com/kper updated https://github.com/llvm/llvm-project/pull/159517

>From 4bda9d44c8648a7db42829d9464d83c28466f28c Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per at protonmail.com>
Date: Thu, 18 Sep 2025 07:15:09 +0000
Subject: [PATCH 1/3] [DAG] Fold urem(urem(A, BCst), Op1Cst) -> urem(A, Op1Cst)

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |  9 +++
 llvm/test/CodeGen/RISCV/urem.ll               | 71 +++++++++++++++++++
 2 files changed, 80 insertions(+)
 create mode 100644 llvm/test/CodeGen/RISCV/urem.ll

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 77bc47f28fc80..8e23282aad0fd 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -54,6 +54,7 @@
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/Metadata.h"
+#include "llvm/IR/PatternMatch.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/CommandLine.h"
@@ -5405,6 +5406,14 @@ SDValue DAGCombiner::visitREM(SDNode *N) {
   if (SDValue DivRem = useDivRem(N))
     return DivRem.getValue(1);
 
+  // fold urem(urem(A, BCst), Op1Cst) -> urem(A, Op1Cst)
+  SDValue A;
+  APInt Op1Cst, BCCst;
+  if (sd_match(N0, m_URem(m_Value(A), m_ConstInt(BCCst))) &&
+      sd_match(N1, m_ConstInt(Op1Cst)) && BCCst.urem(Op1Cst).isZero()) {
+    return DAG.getNode(ISD::UREM, DL, VT, A, DAG.getConstant(Op1Cst, DL, VT));
+  }
+
   return SDValue();
 }
 
diff --git a/llvm/test/CodeGen/RISCV/urem.ll b/llvm/test/CodeGen/RISCV/urem.ll
new file mode 100644
index 0000000000000..aeec9abd0ed9f
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/urem.ll
@@ -0,0 +1,71 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
+; RUN:   | FileCheck -check-prefixes=CHECK,RV32I %s
+; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
+; RUN:   | FileCheck -check-prefixes=CHECK,RV64I %s
+
+define i32 @fold_urem_constants(i32 %v0) {
+; RV32I-LABEL: fold_urem_constants:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    li a1, 5
+; RV32I-NEXT:    tail __umodsi3
+;
+; RV64I-LABEL: fold_urem_constants:
+; RV64I:       # %bb.0:
+; RV64I-NEXT:    addi sp, sp, -16
+; RV64I-NEXT:    .cfi_def_cfa_offset 16
+; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT:    .cfi_offset ra, -8
+; RV64I-NEXT:    slli a0, a0, 32
+; RV64I-NEXT:    srli a0, a0, 32
+; RV64I-NEXT:    li a1, 5
+; RV64I-NEXT:    call __umoddi3
+; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT:    .cfi_restore ra
+; RV64I-NEXT:    addi sp, sp, 16
+; RV64I-NEXT:    .cfi_def_cfa_offset 0
+; RV64I-NEXT:    ret
+  %v1 = urem i32 %v0, 25
+  %v2 = urem i32 %v1, 5
+  ret i32 %v2
+}
+
+define i32 @dont_test_fold_urem_constants(i32 %v0) {
+; RV32I-LABEL: dont_test_fold_urem_constants:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    .cfi_def_cfa_offset 16
+; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT:    .cfi_offset ra, -4
+; RV32I-NEXT:    li a1, 25
+; RV32I-NEXT:    call __umodsi3
+; RV32I-NEXT:    li a1, 3
+; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT:    .cfi_restore ra
+; RV32I-NEXT:    addi sp, sp, 16
+; RV32I-NEXT:    .cfi_def_cfa_offset 0
+; RV32I-NEXT:    tail __umodsi3
+;
+; RV64I-LABEL: dont_test_fold_urem_constants:
+; RV64I:       # %bb.0:
+; RV64I-NEXT:    addi sp, sp, -16
+; RV64I-NEXT:    .cfi_def_cfa_offset 16
+; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT:    .cfi_offset ra, -8
+; RV64I-NEXT:    slli a0, a0, 32
+; RV64I-NEXT:    srli a0, a0, 32
+; RV64I-NEXT:    li a1, 25
+; RV64I-NEXT:    call __umoddi3
+; RV64I-NEXT:    li a1, 3
+; RV64I-NEXT:    call __umoddi3
+; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT:    .cfi_restore ra
+; RV64I-NEXT:    addi sp, sp, 16
+; RV64I-NEXT:    .cfi_def_cfa_offset 0
+; RV64I-NEXT:    ret
+  %v1 = urem i32 %v0, 25
+  %v2 = urem i32 %v1, 3
+  ret i32 %v2
+}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK: {{.*}}

>From e953dbe41b22f6ad4445ef216a503be8d19168bd Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per at protonmail.com>
Date: Thu, 18 Sep 2025 07:48:53 +0000
Subject: [PATCH 2/3] Removed unused header from debugging

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 8e23282aad0fd..b06b58fd70150 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -54,7 +54,6 @@
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/Metadata.h"
-#include "llvm/IR/PatternMatch.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/CommandLine.h"

>From 220de8672a212a858a0fa11c9dcc17cfee5ae42c Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per at protonmail.com>
Date: Thu, 18 Sep 2025 09:15:57 +0000
Subject: [PATCH 3/3] Fixed typo

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index b06b58fd70150..bc21689637788 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -5407,9 +5407,9 @@ SDValue DAGCombiner::visitREM(SDNode *N) {
 
   // fold urem(urem(A, BCst), Op1Cst) -> urem(A, Op1Cst)
   SDValue A;
-  APInt Op1Cst, BCCst;
-  if (sd_match(N0, m_URem(m_Value(A), m_ConstInt(BCCst))) &&
-      sd_match(N1, m_ConstInt(Op1Cst)) && BCCst.urem(Op1Cst).isZero()) {
+  APInt Op1Cst, BCst;
+  if (sd_match(N0, m_URem(m_Value(A), m_ConstInt(BCst))) &&
+      sd_match(N1, m_ConstInt(Op1Cst)) && BCst.urem(Op1Cst).isZero()) {
     return DAG.getNode(ISD::UREM, DL, VT, A, DAG.getConstant(Op1Cst, DL, VT));
   }
 



More information about the llvm-commits mailing list