[llvm] [InstCombine] Canonicalize `smax(smin(X, MinC), MaxC) -> smin(smax(X, MaxC), MinC)` (PR #136665)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 22 01:21:31 PDT 2025


================
@@ -1924,6 +1924,26 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
       }
     }
 
+    // Canonicalize smax(smin(X, MinC), MaxC) to smin(smax(X, MaxC), MinC)
+    if (IID == Intrinsic::smax) {
+      Constant *MinC, *MaxC;
+      if ((match(I1, m_Constant(MaxC)) &&
+           (match(I0, m_OneUse(m_Intrinsic<Intrinsic::smin>(
+                          m_Value(X), m_Constant(MinC)))) ||
+            match(I0, m_OneUse(m_Intrinsic<Intrinsic::smin>(m_Constant(MinC),
+                                                            m_Value(X)))))) ||
+          (match(I0, m_Constant(MaxC)) &&
+           (match(I1, m_OneUse(m_Intrinsic<Intrinsic::smin>(
+                          m_Value(X), m_Constant(MinC)))) ||
+            match(I1, m_OneUse(m_Intrinsic<Intrinsic::smin>(m_Constant(MinC),
+                                                            m_Value(X))))))) {
+        Value *NewSMax =
----------------
dtcxzyw wrote:

Missing check for `%MinC s>= %MaxC` (It is not guaranteed to be simplified by InstSimplify).
Please add the following vector test: https://alive2.llvm.org/ce/z/vsaCn5
```
define <2 x i8> @src1(<2 x i8> %a) {
  %min = call <2 x i8> @llvm.smin(<2 x i8> %a, <2 x i8> <i8 20, i8 10>)
  %max = call <2 x i8> @llvm.smax(<2 x i8> %min, <2 x i8> <i8 10, i8 0>)
  ret <2 x i8> %max
}

define <2 x i8> @src2(<2 x i8> %a) {
  %min = call <2 x i8> @llvm.smin(<2 x i8> %a, <2 x i8> <i8 0, i8 10>)
  %max = call <2 x i8> @llvm.smax(<2 x i8> %min, <2 x i8> <i8 10, i8 0>)
  ret <2 x i8> %max
}
```

https://github.com/llvm/llvm-project/pull/136665


More information about the llvm-commits mailing list