[llvm] [InstCombine] Fix unexpected overwriting in `foldSelectWithSRem` (PR #89539)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 21 04:46:21 PDT 2024


https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/89539

Fixes #89516 


>From e4e48aa76fe2b48b168bf21d6e7141670bd61ab0 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sun, 21 Apr 2024 19:29:32 +0800
Subject: [PATCH 1/2] [InstCombine] Add pre-commit tests for PR89516. NFC.

---
 llvm/test/Transforms/InstCombine/select-divrem.ll | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/select-divrem.ll b/llvm/test/Transforms/InstCombine/select-divrem.ll
index f007c53359ca5a..5ce149daa937f1 100644
--- a/llvm/test/Transforms/InstCombine/select-divrem.ll
+++ b/llvm/test/Transforms/InstCombine/select-divrem.ll
@@ -343,3 +343,17 @@ define i32 @rem_euclid_pow2_false_arm_folded(i32 %n) {
   %res = select i1 %nonneg, i32 %rem, i32 1
   ret i32 %res
 }
+
+define i8 @pr89516(i8 %n, i8 %x) {
+; CHECK-LABEL: @pr89516(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i8 [[N:%.*]], 0
+; CHECK-NEXT:    [[RES:%.*]] = zext i1 [[TMP1]] to i8
+; CHECK-NEXT:    ret i8 [[RES]]
+;
+  %cond = icmp slt i8 %x, 0
+  %pow2 = shl nuw i8 1, %n
+  %srem = srem i8 1, %pow2
+  %add = add nuw i8 %srem, %pow2
+  %res = select i1 %cond, i8 %add, i8 %srem
+  ret i8 %res
+}

>From 66576d537e7999d64a1b8e6e1cf66e4dcc33b7ef Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sun, 21 Apr 2024 19:33:47 +0800
Subject: [PATCH 2/2] [InstCombine] Fix unexpected overwriting in
 `foldSelectWithSRem`

---
 llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | 2 +-
 llvm/test/Transforms/InstCombine/select-divrem.ll     | 7 +++++--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 0262af28068be7..73600206a55c14 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -2720,7 +2720,7 @@ static Instruction *foldSelectWithSRem(SelectInst &SI, InstCombinerImpl &IC,
   // %cnd = icmp slt i32 %rem, 0
   // %add = add i32 %rem, %n
   // %sel = select i1 %cnd, i32 %add, i32 %rem
-  if (match(TrueVal, m_Add(m_Value(RemRes), m_Value(Remainder))) &&
+  if (match(TrueVal, m_Add(m_Specific(RemRes), m_Value(Remainder))) &&
       match(RemRes, m_SRem(m_Value(Op), m_Specific(Remainder))) &&
       IC.isKnownToBeAPowerOfTwo(Remainder, /*OrZero*/ true) &&
       FalseVal == RemRes)
diff --git a/llvm/test/Transforms/InstCombine/select-divrem.ll b/llvm/test/Transforms/InstCombine/select-divrem.ll
index 5ce149daa937f1..e0c460c37451db 100644
--- a/llvm/test/Transforms/InstCombine/select-divrem.ll
+++ b/llvm/test/Transforms/InstCombine/select-divrem.ll
@@ -346,8 +346,11 @@ define i32 @rem_euclid_pow2_false_arm_folded(i32 %n) {
 
 define i8 @pr89516(i8 %n, i8 %x) {
 ; CHECK-LABEL: @pr89516(
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i8 [[N:%.*]], 0
-; CHECK-NEXT:    [[RES:%.*]] = zext i1 [[TMP1]] to i8
+; CHECK-NEXT:    [[COND:%.*]] = icmp slt i8 [[X:%.*]], 0
+; CHECK-NEXT:    [[POW2:%.*]] = shl nuw i8 1, [[N:%.*]]
+; CHECK-NEXT:    [[SREM:%.*]] = srem i8 1, [[POW2]]
+; CHECK-NEXT:    [[ADD:%.*]] = select i1 [[COND]], i8 [[POW2]], i8 0
+; CHECK-NEXT:    [[RES:%.*]] = add nuw i8 [[SREM]], [[ADD]]
 ; CHECK-NEXT:    ret i8 [[RES]]
 ;
   %cond = icmp slt i8 %x, 0



More information about the llvm-commits mailing list