[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