[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 06:46:06 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/5] [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/5] 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/5] 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));
   }
 

>From 0dc64ea23ca4a09ab9952dd3ab162cbd638548e4 Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per at protonmail.com>
Date: Thu, 18 Sep 2025 12:13:24 +0000
Subject: [PATCH 4/5] [DAG] Fold srem(srem(A, BCst), Op1Cst) -> srem(A, Op1Cst)

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 16 +++-
 llvm/test/CodeGen/RISCV/srem.ll               | 69 +++++++++++++++
 llvm/test/CodeGen/RISCV/urem.ll               | 83 ++++++++++++++++++-
 3 files changed, 163 insertions(+), 5 deletions(-)
 create mode 100644 llvm/test/CodeGen/RISCV/srem.ll

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index bc21689637788..dd36ea21d9b19 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/Type.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/CommandLine.h"
@@ -5406,13 +5407,24 @@ SDValue DAGCombiner::visitREM(SDNode *N) {
     return DivRem.getValue(1);
 
   // fold urem(urem(A, BCst), Op1Cst) -> urem(A, Op1Cst)
+  // iff urem(BCst, Op1Cst) == 0
   SDValue A;
   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()) {
+  if (sd_match(N, m_URem(m_URem(m_Value(A), m_ConstInt(BCst)),
+                         m_ConstInt(Op1Cst))) &&
+      BCst.urem(Op1Cst).isZero()) {
     return DAG.getNode(ISD::UREM, DL, VT, A, DAG.getConstant(Op1Cst, DL, VT));
   }
 
+  // fold srem(srem(A, BCst), Op1Cst) -> srem(A, Op1Cst)
+  // iff srem(BCst, Op1Cst) == 0 && Op1Cst != 1
+  if (sd_match(N, m_SRem(m_SRem(m_Value(A), m_ConstInt(BCst)),
+                         m_ConstInt(Op1Cst))) &&
+      BCst.srem(Op1Cst).isZero() &&
+      Op1Cst.ne(APInt::getAllOnes(Op1Cst.getBitWidth()))) {
+    return DAG.getNode(ISD::SREM, DL, VT, A, DAG.getConstant(Op1Cst, DL, VT));
+  }
+
   return SDValue();
 }
 
diff --git a/llvm/test/CodeGen/RISCV/srem.ll b/llvm/test/CodeGen/RISCV/srem.ll
new file mode 100644
index 0000000000000..9dc6e9b75d1de
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/srem.ll
@@ -0,0 +1,69 @@
+; 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_srem_constants(i32 %v0) {
+; RV32I-LABEL: fold_srem_constants:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    li a1, 5
+; RV32I-NEXT:    tail __modsi3
+;
+; RV64I-LABEL: fold_srem_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:    sext.w a0, a0
+; RV64I-NEXT:    li a1, 5
+; RV64I-NEXT:    call __moddi3
+; 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 = srem i32 %v0, 25
+  %v2 = srem i32 %v1, 5
+  ret i32 %v2
+}
+
+define i32 @dont_fold_srem_constants(i32 %v0) {
+; RV32I-LABEL: dont_fold_srem_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 __modsi3
+; 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 __modsi3
+;
+; RV64I-LABEL: dont_fold_srem_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:    sext.w a0, a0
+; RV64I-NEXT:    li a1, 25
+; RV64I-NEXT:    call __moddi3
+; RV64I-NEXT:    li a1, 3
+; RV64I-NEXT:    call __moddi3
+; 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 = srem i32 %v0, 25
+  %v2 = srem i32 %v1, 3
+  ret i32 %v2
+}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK: {{.*}}
diff --git a/llvm/test/CodeGen/RISCV/urem.ll b/llvm/test/CodeGen/RISCV/urem.ll
index aeec9abd0ed9f..d5c6c65c8b6ba 100644
--- a/llvm/test/CodeGen/RISCV/urem.ll
+++ b/llvm/test/CodeGen/RISCV/urem.ll
@@ -30,8 +30,8 @@ define i32 @fold_urem_constants(i32 %v0) {
   ret i32 %v2
 }
 
-define i32 @dont_test_fold_urem_constants(i32 %v0) {
-; RV32I-LABEL: dont_test_fold_urem_constants:
+define i32 @dont_fold_urem_constants(i32 %v0) {
+; RV32I-LABEL: dont_fold_urem_constants:
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    .cfi_def_cfa_offset 16
@@ -46,7 +46,7 @@ define i32 @dont_test_fold_urem_constants(i32 %v0) {
 ; RV32I-NEXT:    .cfi_def_cfa_offset 0
 ; RV32I-NEXT:    tail __umodsi3
 ;
-; RV64I-LABEL: dont_test_fold_urem_constants:
+; RV64I-LABEL: dont_fold_urem_constants:
 ; RV64I:       # %bb.0:
 ; RV64I-NEXT:    addi sp, sp, -16
 ; RV64I-NEXT:    .cfi_def_cfa_offset 16
@@ -67,5 +67,82 @@ define i32 @dont_test_fold_urem_constants(i32 %v0) {
   %v2 = urem i32 %v1, 3
   ret i32 %v2
 }
+
+define i32 @dont_fold_urem_srem_mixed_constants(i32 %v0) {
+; RV32I-LABEL: dont_fold_urem_srem_mixed_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_fold_urem_srem_mixed_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 = srem i32 %v1, 3
+  ret i32 %v2
+}
+
+define i32 @dont_fold_srem_urem_mixed_constants(i32 %v0) {
+; RV32I-LABEL: dont_fold_srem_urem_mixed_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 __modsi3
+; 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_fold_srem_urem_mixed_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:    sext.w a0, a0
+; RV64I-NEXT:    li a1, 25
+; RV64I-NEXT:    call __moddi3
+; RV64I-NEXT:    slli a0, a0, 32
+; RV64I-NEXT:    srli a0, a0, 32
+; 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 = srem 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 1ac624d1a1b2c140a996390f9fd53f027facd2cb Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per at protonmail.com>
Date: Thu, 18 Sep 2025 13:45:24 +0000
Subject: [PATCH 5/5] Addressed feedback

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |  4 +--
 llvm/test/CodeGen/RISCV/srem.ll               | 16 ++-------
 llvm/test/CodeGen/RISCV/urem.ll               | 36 +++----------------
 3 files changed, 7 insertions(+), 49 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index dd36ea21d9b19..d635b12b499da 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/Type.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/CommandLine.h"
@@ -5420,8 +5419,7 @@ SDValue DAGCombiner::visitREM(SDNode *N) {
   // iff srem(BCst, Op1Cst) == 0 && Op1Cst != 1
   if (sd_match(N, m_SRem(m_SRem(m_Value(A), m_ConstInt(BCst)),
                          m_ConstInt(Op1Cst))) &&
-      BCst.srem(Op1Cst).isZero() &&
-      Op1Cst.ne(APInt::getAllOnes(Op1Cst.getBitWidth()))) {
+      BCst.srem(Op1Cst).isZero() && !Op1Cst.isAllOnes()) {
     return DAG.getNode(ISD::SREM, DL, VT, A, DAG.getConstant(Op1Cst, DL, VT));
   }
 
diff --git a/llvm/test/CodeGen/RISCV/srem.ll b/llvm/test/CodeGen/RISCV/srem.ll
index 9dc6e9b75d1de..55a1850f18291 100644
--- a/llvm/test/CodeGen/RISCV/srem.ll
+++ b/llvm/test/CodeGen/RISCV/srem.ll
@@ -4,7 +4,7 @@
 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
 ; RUN:   | FileCheck -check-prefixes=CHECK,RV64I %s
 
-define i32 @fold_srem_constants(i32 %v0) {
+define i32 @fold_srem_constants(i32 %v0) nounwind {
 ; RV32I-LABEL: fold_srem_constants:
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    li a1, 5
@@ -13,53 +13,41 @@ define i32 @fold_srem_constants(i32 %v0) {
 ; RV64I-LABEL: fold_srem_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:    sext.w a0, a0
 ; RV64I-NEXT:    li a1, 5
 ; RV64I-NEXT:    call __moddi3
 ; 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 = srem i32 %v0, 25
   %v2 = srem i32 %v1, 5
   ret i32 %v2
 }
 
-define i32 @dont_fold_srem_constants(i32 %v0) {
+define i32 @dont_fold_srem_constants(i32 %v0) nounwind {
 ; RV32I-LABEL: dont_fold_srem_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 __modsi3
 ; 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 __modsi3
 ;
 ; RV64I-LABEL: dont_fold_srem_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:    sext.w a0, a0
 ; RV64I-NEXT:    li a1, 25
 ; RV64I-NEXT:    call __moddi3
 ; RV64I-NEXT:    li a1, 3
 ; RV64I-NEXT:    call __moddi3
 ; 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 = srem i32 %v0, 25
   %v2 = srem i32 %v1, 3
diff --git a/llvm/test/CodeGen/RISCV/urem.ll b/llvm/test/CodeGen/RISCV/urem.ll
index d5c6c65c8b6ba..faeeb396a698b 100644
--- a/llvm/test/CodeGen/RISCV/urem.ll
+++ b/llvm/test/CodeGen/RISCV/urem.ll
@@ -4,7 +4,7 @@
 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
 ; RUN:   | FileCheck -check-prefixes=CHECK,RV64I %s
 
-define i32 @fold_urem_constants(i32 %v0) {
+define i32 @fold_urem_constants(i32 %v0) nounwind {
 ; RV32I-LABEL: fold_urem_constants:
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    li a1, 5
@@ -13,45 +13,35 @@ define i32 @fold_urem_constants(i32 %v0) {
 ; 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_fold_urem_constants(i32 %v0) {
+define i32 @dont_fold_urem_constants(i32 %v0) nounwind {
 ; RV32I-LABEL: dont_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_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
@@ -59,37 +49,29 @@ define i32 @dont_fold_urem_constants(i32 %v0) {
 ; 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
 }
 
-define i32 @dont_fold_urem_srem_mixed_constants(i32 %v0) {
+define i32 @dont_fold_urem_srem_mixed_constants(i32 %v0) nounwind {
 ; RV32I-LABEL: dont_fold_urem_srem_mixed_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_fold_urem_srem_mixed_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
@@ -97,37 +79,29 @@ define i32 @dont_fold_urem_srem_mixed_constants(i32 %v0) {
 ; 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 = srem i32 %v1, 3
   ret i32 %v2
 }
 
-define i32 @dont_fold_srem_urem_mixed_constants(i32 %v0) {
+define i32 @dont_fold_srem_urem_mixed_constants(i32 %v0) nounwind {
 ; RV32I-LABEL: dont_fold_srem_urem_mixed_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 __modsi3
 ; 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_fold_srem_urem_mixed_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:    sext.w a0, a0
 ; RV64I-NEXT:    li a1, 25
 ; RV64I-NEXT:    call __moddi3
@@ -136,9 +110,7 @@ define i32 @dont_fold_srem_urem_mixed_constants(i32 %v0) {
 ; 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 = srem i32 %v0, 25
   %v2 = urem i32 %v1, 3



More information about the llvm-commits mailing list