[llvm] [InstCombine] Canonicalize `max(min(X, MinC), MaxC) -> min(max(X, MaxC), MinC)` (PR #136665)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 22 07:12:07 PDT 2025
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/136665
>From 986fc2cc8714b18224bed851659400903ad50eef Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Tue, 22 Apr 2025 15:47:45 +0800
Subject: [PATCH 1/3] pre-commit tests
---
.../InstCombine/max-min-canonicalize.ll | 345 ++++++++++++++++++
1 file changed, 345 insertions(+)
create mode 100644 llvm/test/Transforms/InstCombine/max-min-canonicalize.ll
diff --git a/llvm/test/Transforms/InstCombine/max-min-canonicalize.ll b/llvm/test/Transforms/InstCombine/max-min-canonicalize.ll
new file mode 100644
index 0000000000000..48e4663619356
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/max-min-canonicalize.ll
@@ -0,0 +1,345 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+; smax(smin(X, MinC), MaxC) -> smin(smax(X, MaxC), MinC)
+; umax(umin(X, MinC), MaxC) -> umin(smax(X, MaxC), MinC)
+
+
+define i16 @smax_smin(i16 %x) {
+; CHECK-LABEL: define i16 @smax_smin(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.smin.i16(i16 [[X]], i16 255)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smax.i16(i16 [[MIN]], i16 -1)
+; CHECK-NEXT: ret i16 [[MAX]]
+;
+ %min = call i16 @llvm.smin.i16(i16 %x, i16 255)
+ %max = call i16 @llvm.smax.i16(i16 %min, i16 -1)
+ ret i16 %max
+}
+
+define i16 @umax_umin(i16 %x) {
+; CHECK-LABEL: define i16 @umax_umin(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.umin.i16(i16 [[X]], i16 255)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[MIN]], i16 63)
+; CHECK-NEXT: ret i16 [[MAX]]
+;
+ %min = call i16 @llvm.umin.i16(i16 %x, i16 255)
+ %max = call i16 @llvm.umax.i16(i16 %min, i16 63)
+ ret i16 %max
+}
+
+define i16 @smax_smin_commute0(i16 %x) {
+; CHECK-LABEL: define i16 @smax_smin_commute0(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.smin.i16(i16 [[X]], i16 127)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smax.i16(i16 [[MIN]], i16 -128)
+; CHECK-NEXT: ret i16 [[MAX]]
+;
+ %min = call i16 @llvm.smin.i16(i16 %x, i16 127)
+ %max = call i16 @llvm.smax.i16(i16 %min, i16 -128)
+ ret i16 %max
+}
+
+define i16 @umax_umin_commute0(i16 %x) {
+; CHECK-LABEL: define i16 @umax_umin_commute0(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.umin.i16(i16 [[X]], i16 255)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[MIN]], i16 127)
+; CHECK-NEXT: ret i16 [[MAX]]
+;
+ %min = call i16 @llvm.umin.i16(i16 %x, i16 255)
+ %max = call i16 @llvm.umax.i16(i16 %min, i16 127)
+ ret i16 %max
+}
+
+define i16 @smax_smin_commute1(i16 %x) {
+; CHECK-LABEL: define i16 @smax_smin_commute1(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.smin.i16(i16 [[X]], i16 127)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smax.i16(i16 [[MIN]], i16 -128)
+; CHECK-NEXT: ret i16 [[MAX]]
+;
+ %min = call i16 @llvm.smin.i16(i16 127, i16 %x)
+ %max = call i16 @llvm.smax.i16(i16 %min, i16 -128)
+ ret i16 %max
+}
+
+define i16 @umax_umin_commute1(i16 %x) {
+; CHECK-LABEL: define i16 @umax_umin_commute1(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.umin.i16(i16 [[X]], i16 255)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[MIN]], i16 127)
+; CHECK-NEXT: ret i16 [[MAX]]
+;
+ %min = call i16 @llvm.umin.i16(i16 255, i16 %x)
+ %max = call i16 @llvm.umax.i16(i16 %min, i16 127)
+ ret i16 %max
+}
+
+define i16 @smax_smin_commute2(i16 %x) {
+; CHECK-LABEL: define i16 @smax_smin_commute2(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.smin.i16(i16 [[X]], i16 127)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smax.i16(i16 [[MIN]], i16 -128)
+; CHECK-NEXT: ret i16 [[MAX]]
+;
+ %min = call i16 @llvm.smin.i16(i16 %x, i16 127)
+ %max = call i16 @llvm.smax.i16(i16 -128, i16 %min)
+ ret i16 %max
+}
+
+define i16 @umax_umin_commute2(i16 %x) {
+; CHECK-LABEL: define i16 @umax_umin_commute2(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.umin.i16(i16 [[X]], i16 255)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[MIN]], i16 127)
+; CHECK-NEXT: ret i16 [[MAX]]
+;
+ %min = call i16 @llvm.umin.i16(i16 %x, i16 255)
+ %max = call i16 @llvm.umax.i16(i16 127, i16 %min)
+ ret i16 %max
+}
+
+define i16 @smax_smin_commute3(i16 %x) {
+; CHECK-LABEL: define i16 @smax_smin_commute3(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.smin.i16(i16 [[X]], i16 127)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smax.i16(i16 [[MIN]], i16 -128)
+; CHECK-NEXT: ret i16 [[MAX]]
+;
+ %min = call i16 @llvm.smin.i16(i16 %x, i16 127)
+ %max = call i16 @llvm.smax.i16(i16 %min, i16 -128)
+ ret i16 %max
+}
+
+define i16 @umax_umin_commute3(i16 %x) {
+; CHECK-LABEL: define i16 @umax_umin_commute3(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.umin.i16(i16 [[X]], i16 255)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[MIN]], i16 127)
+; CHECK-NEXT: ret i16 [[MAX]]
+;
+ %min = call i16 @llvm.umin.i16(i16 %x, i16 255)
+ %max = call i16 @llvm.umax.i16(i16 %min, i16 127)
+ ret i16 %max
+}
+
+define <2 x i16> @smax_smin_v2i16(<2 x i16> %x) {
+; CHECK-LABEL: define <2 x i16> @smax_smin_v2i16(
+; CHECK-SAME: <2 x i16> [[X:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call <2 x i16> @llvm.smin.v2i16(<2 x i16> [[X]], <2 x i16> splat (i16 127))
+; CHECK-NEXT: [[MAX:%.*]] = call <2 x i16> @llvm.smax.v2i16(<2 x i16> [[MIN]], <2 x i16> splat (i16 -128))
+; CHECK-NEXT: ret <2 x i16> [[MAX]]
+;
+ %min = call <2 x i16> @llvm.smin.v2i16(<2 x i16> %x, <2 x i16> splat (i16 127))
+ %max = call <2 x i16> @llvm.smax.v2i16(<2 x i16> %min, <2 x i16> splat (i16 -128))
+ ret <2 x i16> %max
+}
+
+define <2 x i16> @umax_umin_v2i16(<2 x i16> %x) {
+; CHECK-LABEL: define <2 x i16> @umax_umin_v2i16(
+; CHECK-SAME: <2 x i16> [[X:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call <2 x i16> @llvm.umin.v2i16(<2 x i16> [[X]], <2 x i16> splat (i16 255))
+; CHECK-NEXT: [[MAX:%.*]] = call <2 x i16> @llvm.umax.v2i16(<2 x i16> [[MIN]], <2 x i16> splat (i16 127))
+; CHECK-NEXT: ret <2 x i16> [[MAX]]
+;
+ %min = call <2 x i16> @llvm.umin.v2i16(<2 x i16> %x, <2 x i16> splat (i16 255))
+ %max = call <2 x i16> @llvm.umax.v2i16(<2 x i16> %min, <2 x i16> splat (i16 127))
+ ret <2 x i16> %max
+}
+
+define <2 x i8> @smax_smin_v2i16_nonsplat_1(<2 x i8> %a) {
+; CHECK-LABEL: define <2 x i8> @smax_smin_v2i16_nonsplat_1(
+; CHECK-SAME: <2 x i8> [[A:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call <2 x i8> @llvm.smin.v2i8(<2 x i8> [[A]], <2 x i8> <i8 20, i8 10>)
+; CHECK-NEXT: [[MAX:%.*]] = call <2 x i8> @llvm.smax.v2i8(<2 x i8> [[MIN]], <2 x i8> <i8 10, i8 0>)
+; CHECK-NEXT: ret <2 x i8> [[MAX]]
+;
+ %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 i16> @umax_umin_v2i16_nonsplat_1(<2 x i16> %a) {
+; CHECK-LABEL: define <2 x i16> @umax_umin_v2i16_nonsplat_1(
+; CHECK-SAME: <2 x i16> [[A:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call <2 x i16> @llvm.umin.v2i16(<2 x i16> [[A]], <2 x i16> <i16 20, i16 10>)
+; CHECK-NEXT: [[MAX:%.*]] = call <2 x i16> @llvm.umax.v2i16(<2 x i16> [[MIN]], <2 x i16> <i16 10, i16 1>)
+; CHECK-NEXT: ret <2 x i16> [[MAX]]
+;
+ %min = call <2 x i16> @llvm.umin(<2 x i16> %a, <2 x i16> <i16 20, i16 10>)
+ %max = call <2 x i16> @llvm.umax(<2 x i16> %min, <2 x i16> <i16 10, i16 1>)
+ ret <2 x i16> %max
+}
+
+define <2 x i8> @smax_smin_v2i16_nonsplat_2(<2 x i8> %a) {
+; CHECK-LABEL: define <2 x i8> @smax_smin_v2i16_nonsplat_2(
+; CHECK-SAME: <2 x i8> [[A:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call <2 x i8> @llvm.smin.v2i8(<2 x i8> [[A]], <2 x i8> <i8 0, i8 10>)
+; CHECK-NEXT: [[MAX:%.*]] = call <2 x i8> @llvm.smax.v2i8(<2 x i8> [[MIN]], <2 x i8> <i8 10, i8 0>)
+; CHECK-NEXT: ret <2 x i8> [[MAX]]
+;
+ %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
+}
+
+define <2 x i16> @umax_umin_v2i16_nonsplat_2(<2 x i16> %a) {
+; CHECK-LABEL: define <2 x i16> @umax_umin_v2i16_nonsplat_2(
+; CHECK-SAME: <2 x i16> [[A:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call <2 x i16> @llvm.umin.v2i16(<2 x i16> [[A]], <2 x i16> <i16 1, i16 10>)
+; CHECK-NEXT: [[MAX:%.*]] = call <2 x i16> @llvm.umax.v2i16(<2 x i16> [[MIN]], <2 x i16> <i16 10, i16 1>)
+; CHECK-NEXT: ret <2 x i16> [[MAX]]
+;
+ %min = call <2 x i16> @llvm.umin(<2 x i16> %a, <2 x i16> <i16 1, i16 10>)
+ %max = call <2 x i16> @llvm.umax(<2 x i16> %min, <2 x i16> <i16 10, i16 1>)
+ ret <2 x i16> %max
+}
+
+declare void @use(i16)
+
+define i16 @smax_smin_used(i16 %x) {
+; CHECK-LABEL: define i16 @smax_smin_used(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.smin.i16(i16 [[X]], i16 127)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smax.i16(i16 [[MIN]], i16 -128)
+; CHECK-NEXT: call void @use(i16 [[MIN]])
+; CHECK-NEXT: ret i16 [[MAX]]
+;
+ %min = call i16 @llvm.smin.i16(i16 %x, i16 127)
+ %max = call i16 @llvm.smax.i16(i16 %min, i16 -128)
+ call void @use(i16 %min)
+ ret i16 %max
+}
+
+define i16 @umax_umin_used(i16 %x) {
+; CHECK-LABEL: define i16 @umax_umin_used(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.umin.i16(i16 [[X]], i16 255)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[MIN]], i16 127)
+; CHECK-NEXT: call void @use(i16 [[MIN]])
+; CHECK-NEXT: ret i16 [[MAX]]
+;
+ %min = call i16 @llvm.umin.i16(i16 %x, i16 255)
+ %max = call i16 @llvm.umax.i16(i16 %min, i16 127)
+ call void @use(i16 %min)
+ ret i16 %max
+}
+
+
+define i16 @smax_smin_i16_limits(i16 %x) {
+; CHECK-LABEL: define i16 @smax_smin_i16_limits(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: ret i16 [[X]]
+;
+ %min = call i16 @llvm.smin.i16(i16 %x, i16 32767)
+ %max = call i16 @llvm.smax.i16(i16 %min, i16 -32768)
+ ret i16 %max
+}
+
+define i16 @umax_umin_i16_limits(i16 %x) {
+; CHECK-LABEL: define i16 @umax_umin_i16_limits(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: ret i16 [[X]]
+;
+ %min = call i16 @llvm.umin.i16(i16 %x, i16 65535)
+ %max = call i16 @llvm.umax.i16(i16 %min, i16 0)
+ ret i16 %max
+}
+
+define i16 @min_smax_smin_nested(i16 %x) {
+; CHECK-LABEL: define i16 @min_smax_smin_nested(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[MIN1:%.*]] = call i16 @llvm.smin.i16(i16 [[X]], i16 255)
+; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.smax.i16(i16 [[MIN1]], i16 -128)
+; CHECK-NEXT: [[MIN2:%.*]] = call i16 @llvm.smin.i16(i16 [[TMP1]], i16 127)
+; CHECK-NEXT: ret i16 [[MIN2]]
+;
+ %min1 = call i16 @llvm.smin.i16(i16 %x, i16 255)
+ %max = call i16 @llvm.smax.i16(i16 %min1, i16 -128)
+ %min2 = call i16 @llvm.smin.i16(i16 %max, i16 127)
+ ret i16 %min2
+}
+
+define i16 @umax_umin_nested(i16 %x) {
+; CHECK-LABEL: define i16 @umax_umin_nested(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[MIN1:%.*]] = call i16 @llvm.umin.i16(i16 [[X]], i16 255)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[MIN1]], i16 63)
+; CHECK-NEXT: [[MIN2:%.*]] = call i16 @llvm.umin.i16(i16 [[MAX]], i16 127)
+; CHECK-NEXT: ret i16 [[MIN2]]
+;
+ %min1 = call i16 @llvm.umin.i16(i16 %x, i16 255)
+ %max = call i16 @llvm.umax.i16(i16 %min1, i16 63)
+ %min2 = call i16 @llvm.umin.i16(i16 %max, i16 127)
+ ret i16 %min2
+}
+
+define i16 @smax_smin_cmax_sgt_cmin(i16 %x) {
+; CHECK-LABEL: define i16 @smax_smin_cmax_sgt_cmin(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: ret i16 127
+;
+ %min = call i16 @llvm.smin.i16(i16 %x, i16 126)
+ %max = call i16 @llvm.smax.i16(i16 %min, i16 127)
+ ret i16 %max
+}
+
+define i16 @umax_umin_cmax_ugt_cmin(i16 %x) {
+; CHECK-LABEL: define i16 @umax_umin_cmax_ugt_cmin(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: ret i16 127
+;
+ %min = call i16 @llvm.umin.i16(i16 %x, i16 126)
+ %max = call i16 @llvm.umax.i16(i16 %min, i16 127)
+ ret i16 %max
+}
+
+define i16 @smax_smin_variables(i16 %x, i16 %y, i16 %z) {
+; CHECK-LABEL: define i16 @smax_smin_variables(
+; CHECK-SAME: i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.smin.i16(i16 [[X]], i16 [[Y]])
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smax.i16(i16 [[MIN]], i16 [[Z]])
+; CHECK-NEXT: ret i16 [[MAX]]
+;
+ %min = call i16 @llvm.smin.i16(i16 %x, i16 %y)
+ %max = call i16 @llvm.smax.i16(i16 %min, i16 %z)
+ ret i16 %max
+}
+
+define i16 @umax_umin_variables(i16 %x, i16 %y, i16 %z) {
+; CHECK-LABEL: define i16 @umax_umin_variables(
+; CHECK-SAME: i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {
+; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.umin.i16(i16 [[X]], i16 [[Y]])
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[MIN]], i16 [[Z]])
+; CHECK-NEXT: ret i16 [[MAX]]
+;
+ %min = call i16 @llvm.umin.i16(i16 %x, i16 %y)
+ %max = call i16 @llvm.umax.i16(i16 %min, i16 %z)
+ ret i16 %max
+}
+
+define i16 @smin_smax(i16 %x) {
+; CHECK-LABEL: define i16 @smin_smax(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smax.i16(i16 [[X]], i16 -128)
+; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.smin.i16(i16 [[MAX]], i16 127)
+; CHECK-NEXT: ret i16 [[MIN]]
+;
+ %max = call i16 @llvm.smax.i16(i16 %x, i16 -128)
+ %min = call i16 @llvm.smin.i16(i16 %max, i16 127)
+ ret i16 %min
+}
+
+define i16 @umin_umax(i16 %x) {
+; CHECK-LABEL: define i16 @umin_umax(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[X]], i16 127)
+; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.umin.i16(i16 [[MAX]], i16 255)
+; CHECK-NEXT: ret i16 [[MIN]]
+;
+ %max = call i16 @llvm.umax.i16(i16 %x, i16 127)
+ %min = call i16 @llvm.umin.i16(i16 %max, i16 255)
+ ret i16 %min
+}
>From 3d13662dfe9e4aa03e6a0041034381b50820af84 Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Tue, 22 Apr 2025 20:03:04 +0800
Subject: [PATCH 2/3] [InstCombine] Canonicalize `max(min(X, MinC), MaxC) ->
min(max(X, MaxC), MinC)`
---
.../InstCombine/InstCombineCalls.cpp | 23 ++++++++
.../Transforms/InstCombine/clamp-to-minmax.ll | 28 +++++-----
.../InstCombine/max-min-canonicalize.ll | 54 +++++++++----------
.../Transforms/InstCombine/max_known_bits.ll | 24 ++++-----
.../Transforms/InstCombine/minmax-fold.ll | 34 ++++++------
.../InstCombine/minmax-intrinsics.ll | 14 ++---
llvm/test/Transforms/InstCombine/sadd_sat.ll | 40 +++++++-------
.../Transforms/InstCombine/select-min-max.ll | 8 +--
8 files changed, 123 insertions(+), 102 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 38519d81fce8d..7e10638cd6e29 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1924,6 +1924,29 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
}
}
+ // smax(smin(X, MinC), MaxC) -> smin(smax(X, MaxC), MinC) if MinC s>= MaxC
+ // umax(umin(X, MinC), MaxC) -> umin(umax(X, MaxC), MinC) if MinC u>= MaxC
+ const APInt *MinC, *MaxC;
+ auto CreateTransposedMaxMin = [&](bool IsSigned) {
+ auto MaxIID = IsSigned ? Intrinsic::smax : Intrinsic::umax;
+ auto MinIID = IsSigned ? Intrinsic::smin : Intrinsic::umin;
+ Value *NewMax = Builder.CreateBinaryIntrinsic(
+ MaxIID, X, ConstantInt::get(X->getType(), *MaxC));
+ return replaceInstUsesWith(
+ *II, Builder.CreateBinaryIntrinsic(
+ MinIID, NewMax, ConstantInt::get(X->getType(), *MinC)));
+ };
+ if (IID == Intrinsic::smax &&
+ match(I0, m_OneUse(m_Intrinsic<Intrinsic::smin>(m_Value(X),
+ m_APInt(MinC)))) &&
+ match(I1, m_APInt(MaxC)) && MinC->sgt(*MaxC))
+ return CreateTransposedMaxMin(true);
+ if (IID == Intrinsic::umax &&
+ match(I0, m_OneUse(m_Intrinsic<Intrinsic::umin>(m_Value(X),
+ m_APInt(MinC)))) &&
+ match(I1, m_APInt(MaxC)) && MinC->ugt(*MaxC))
+ return CreateTransposedMaxMin(false);
+
// umin(i1 X, i1 Y) -> and i1 X, Y
// smax(i1 X, i1 Y) -> and i1 X, Y
if ((IID == Intrinsic::umin || IID == Intrinsic::smax) &&
diff --git a/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll b/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll
index 478d437847127..b557c0dbe2629 100644
--- a/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll
+++ b/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll
@@ -83,7 +83,7 @@ define float @clamp_float_fast_unordered_strict_maxmin(float %x) {
; (X <= C1) ? C1 : MIN(X, C2)
define float @clamp_float_fast_unordered_nonstrict_maxmin(float %x) {
; CHECK-LABEL: @clamp_float_fast_unordered_nonstrict_maxmin(
-; CHECK-NEXT: [[MIN:%.*]] = call fast float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
+; CHECK-NEXT: [[MIN:%.*]] = call fast float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast ule float [[X]], 1.000000e+00
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
; CHECK-NEXT: ret float [[R]]
@@ -98,7 +98,7 @@ define float @clamp_float_fast_unordered_nonstrict_maxmin(float %x) {
; (X > C1) ? C1 : MAX(X, C2)
define float @clamp_float_fast_unordered_strict_minmax(float %x) {
; CHECK-LABEL: @clamp_float_fast_unordered_strict_minmax(
-; CHECK-NEXT: [[MAX:%.*]] = call fast float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
+; CHECK-NEXT: [[MAX:%.*]] = call fast float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast ugt float [[X]], 2.550000e+02
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
; CHECK-NEXT: ret float [[R]]
@@ -113,7 +113,7 @@ define float @clamp_float_fast_unordered_strict_minmax(float %x) {
; (X >= C1) ? C1 : MAX(X, C2)
define float @clamp_float_fast_unordered_nonstrict_minmax(float %x) {
; CHECK-LABEL: @clamp_float_fast_unordered_nonstrict_minmax(
-; CHECK-NEXT: [[MAX:%.*]] = call fast float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
+; CHECK-NEXT: [[MAX:%.*]] = call fast float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast uge float [[X]], 2.550000e+02
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
; CHECK-NEXT: ret float [[R]]
@@ -147,7 +147,7 @@ define float @clamp_test_1(float %x) {
; Like @clamp_test_1 but HighConst < LowConst
define float @clamp_negative_wrong_const(float %x) {
; CHECK-LABEL: @clamp_negative_wrong_const(
-; CHECK-NEXT: [[INNER_SEL:%.*]] = call fast float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
+; CHECK-NEXT: [[INNER_SEL:%.*]] = call fast float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
; CHECK-NEXT: [[OUTER_CMP:%.*]] = fcmp fast ugt float [[X]], 5.120000e+02
; CHECK-NEXT: [[R:%.*]] = select i1 [[OUTER_CMP]], float [[INNER_SEL]], float 5.120000e+02
; CHECK-NEXT: ret float [[R]]
@@ -162,7 +162,7 @@ define float @clamp_negative_wrong_const(float %x) {
; Like @clamp_test_1 but both are min
define float @clamp_negative_same_op(float %x) {
; CHECK-LABEL: @clamp_negative_same_op(
-; CHECK-NEXT: [[INNER_SEL:%.*]] = call fast float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
+; CHECK-NEXT: [[INNER_SEL:%.*]] = call fast float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
; CHECK-NEXT: [[OUTER_CMP:%.*]] = fcmp fast ult float [[X]], 1.000000e+00
; CHECK-NEXT: [[R:%.*]] = select i1 [[OUTER_CMP]], float [[INNER_SEL]], float 1.000000e+00
; CHECK-NEXT: ret float [[R]]
@@ -500,9 +500,9 @@ define float @ui64_clamp_and_cast_to_float(i64 %x) {
define float @mixed_clamp_to_float_1(i32 %x) {
; CHECK-LABEL: @mixed_clamp_to_float_1(
-; CHECK-NEXT: [[SI_MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255)
-; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.smax.i32(i32 [[SI_MIN]], i32 1)
-; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[R1]] to float
+; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.smax.i32(i32 [[SI_MIN:%.*]], i32 1)
+; CHECK-NEXT: [[R2:%.*]] = call i32 @llvm.smin.i32(i32 [[R1]], i32 255)
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[R2]] to float
; CHECK-NEXT: ret float [[R]]
;
%si_min_cmp = icmp sgt i32 %x, 255
@@ -535,9 +535,9 @@ define i32 @mixed_clamp_to_i32_1(float %x) {
define float @mixed_clamp_to_float_2(i32 %x) {
; CHECK-LABEL: @mixed_clamp_to_float_2(
-; CHECK-NEXT: [[SI_MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255)
-; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.smax.i32(i32 [[SI_MIN]], i32 1)
-; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[R1]] to float
+; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.smax.i32(i32 [[SI_MIN:%.*]], i32 1)
+; CHECK-NEXT: [[R2:%.*]] = call i32 @llvm.smin.i32(i32 [[R1]], i32 255)
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[R2]] to float
; CHECK-NEXT: ret float [[R]]
;
%si_min_cmp = icmp sgt i32 %x, 255
@@ -568,9 +568,9 @@ define i32 @mixed_clamp_to_i32_2(float %x) {
define <2 x float> @mixed_clamp_to_float_vec(<2 x i32> %x) {
; CHECK-LABEL: @mixed_clamp_to_float_vec(
-; CHECK-NEXT: [[SI_MIN:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> splat (i32 255))
-; CHECK-NEXT: [[R1:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[SI_MIN]], <2 x i32> splat (i32 1))
-; CHECK-NEXT: [[R:%.*]] = uitofp nneg <2 x i32> [[R1]] to <2 x float>
+; CHECK-NEXT: [[R1:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[SI_MIN:%.*]], <2 x i32> splat (i32 1))
+; CHECK-NEXT: [[R2:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[R1]], <2 x i32> splat (i32 255))
+; CHECK-NEXT: [[R:%.*]] = uitofp nneg <2 x i32> [[R2]] to <2 x float>
; CHECK-NEXT: ret <2 x float> [[R]]
;
%si_min_cmp = icmp sgt <2 x i32> %x, <i32 255, i32 255>
diff --git a/llvm/test/Transforms/InstCombine/max-min-canonicalize.ll b/llvm/test/Transforms/InstCombine/max-min-canonicalize.ll
index 48e4663619356..25547073e17d9 100644
--- a/llvm/test/Transforms/InstCombine/max-min-canonicalize.ll
+++ b/llvm/test/Transforms/InstCombine/max-min-canonicalize.ll
@@ -8,8 +8,8 @@
define i16 @smax_smin(i16 %x) {
; CHECK-LABEL: define i16 @smax_smin(
; CHECK-SAME: i16 [[X:%.*]]) {
-; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.smin.i16(i16 [[X]], i16 255)
-; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smax.i16(i16 [[MIN]], i16 -1)
+; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.smax.i16(i16 [[X]], i16 -1)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smin.i16(i16 [[TMP1]], i16 255)
; CHECK-NEXT: ret i16 [[MAX]]
;
%min = call i16 @llvm.smin.i16(i16 %x, i16 255)
@@ -20,8 +20,8 @@ define i16 @smax_smin(i16 %x) {
define i16 @umax_umin(i16 %x) {
; CHECK-LABEL: define i16 @umax_umin(
; CHECK-SAME: i16 [[X:%.*]]) {
-; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.umin.i16(i16 [[X]], i16 255)
-; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[MIN]], i16 63)
+; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.umax.i16(i16 [[X]], i16 63)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umin.i16(i16 [[TMP1]], i16 255)
; CHECK-NEXT: ret i16 [[MAX]]
;
%min = call i16 @llvm.umin.i16(i16 %x, i16 255)
@@ -32,8 +32,8 @@ define i16 @umax_umin(i16 %x) {
define i16 @smax_smin_commute0(i16 %x) {
; CHECK-LABEL: define i16 @smax_smin_commute0(
; CHECK-SAME: i16 [[X:%.*]]) {
-; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.smin.i16(i16 [[X]], i16 127)
-; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smax.i16(i16 [[MIN]], i16 -128)
+; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.smax.i16(i16 [[X]], i16 -128)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smin.i16(i16 [[TMP1]], i16 127)
; CHECK-NEXT: ret i16 [[MAX]]
;
%min = call i16 @llvm.smin.i16(i16 %x, i16 127)
@@ -44,8 +44,8 @@ define i16 @smax_smin_commute0(i16 %x) {
define i16 @umax_umin_commute0(i16 %x) {
; CHECK-LABEL: define i16 @umax_umin_commute0(
; CHECK-SAME: i16 [[X:%.*]]) {
-; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.umin.i16(i16 [[X]], i16 255)
-; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[MIN]], i16 127)
+; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.umax.i16(i16 [[X]], i16 127)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umin.i16(i16 [[TMP1]], i16 255)
; CHECK-NEXT: ret i16 [[MAX]]
;
%min = call i16 @llvm.umin.i16(i16 %x, i16 255)
@@ -56,8 +56,8 @@ define i16 @umax_umin_commute0(i16 %x) {
define i16 @smax_smin_commute1(i16 %x) {
; CHECK-LABEL: define i16 @smax_smin_commute1(
; CHECK-SAME: i16 [[X:%.*]]) {
-; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.smin.i16(i16 [[X]], i16 127)
-; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smax.i16(i16 [[MIN]], i16 -128)
+; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.smax.i16(i16 [[X]], i16 -128)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smin.i16(i16 [[TMP1]], i16 127)
; CHECK-NEXT: ret i16 [[MAX]]
;
%min = call i16 @llvm.smin.i16(i16 127, i16 %x)
@@ -68,8 +68,8 @@ define i16 @smax_smin_commute1(i16 %x) {
define i16 @umax_umin_commute1(i16 %x) {
; CHECK-LABEL: define i16 @umax_umin_commute1(
; CHECK-SAME: i16 [[X:%.*]]) {
-; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.umin.i16(i16 [[X]], i16 255)
-; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[MIN]], i16 127)
+; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.umax.i16(i16 [[X]], i16 127)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umin.i16(i16 [[TMP1]], i16 255)
; CHECK-NEXT: ret i16 [[MAX]]
;
%min = call i16 @llvm.umin.i16(i16 255, i16 %x)
@@ -80,8 +80,8 @@ define i16 @umax_umin_commute1(i16 %x) {
define i16 @smax_smin_commute2(i16 %x) {
; CHECK-LABEL: define i16 @smax_smin_commute2(
; CHECK-SAME: i16 [[X:%.*]]) {
-; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.smin.i16(i16 [[X]], i16 127)
-; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smax.i16(i16 [[MIN]], i16 -128)
+; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.smax.i16(i16 [[X]], i16 -128)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smin.i16(i16 [[TMP1]], i16 127)
; CHECK-NEXT: ret i16 [[MAX]]
;
%min = call i16 @llvm.smin.i16(i16 %x, i16 127)
@@ -92,8 +92,8 @@ define i16 @smax_smin_commute2(i16 %x) {
define i16 @umax_umin_commute2(i16 %x) {
; CHECK-LABEL: define i16 @umax_umin_commute2(
; CHECK-SAME: i16 [[X:%.*]]) {
-; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.umin.i16(i16 [[X]], i16 255)
-; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[MIN]], i16 127)
+; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.umax.i16(i16 [[X]], i16 127)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umin.i16(i16 [[TMP1]], i16 255)
; CHECK-NEXT: ret i16 [[MAX]]
;
%min = call i16 @llvm.umin.i16(i16 %x, i16 255)
@@ -104,8 +104,8 @@ define i16 @umax_umin_commute2(i16 %x) {
define i16 @smax_smin_commute3(i16 %x) {
; CHECK-LABEL: define i16 @smax_smin_commute3(
; CHECK-SAME: i16 [[X:%.*]]) {
-; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.smin.i16(i16 [[X]], i16 127)
-; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smax.i16(i16 [[MIN]], i16 -128)
+; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.smax.i16(i16 [[X]], i16 -128)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smin.i16(i16 [[TMP1]], i16 127)
; CHECK-NEXT: ret i16 [[MAX]]
;
%min = call i16 @llvm.smin.i16(i16 %x, i16 127)
@@ -116,8 +116,8 @@ define i16 @smax_smin_commute3(i16 %x) {
define i16 @umax_umin_commute3(i16 %x) {
; CHECK-LABEL: define i16 @umax_umin_commute3(
; CHECK-SAME: i16 [[X:%.*]]) {
-; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.umin.i16(i16 [[X]], i16 255)
-; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[MIN]], i16 127)
+; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.umax.i16(i16 [[X]], i16 127)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umin.i16(i16 [[TMP1]], i16 255)
; CHECK-NEXT: ret i16 [[MAX]]
;
%min = call i16 @llvm.umin.i16(i16 %x, i16 255)
@@ -128,8 +128,8 @@ define i16 @umax_umin_commute3(i16 %x) {
define <2 x i16> @smax_smin_v2i16(<2 x i16> %x) {
; CHECK-LABEL: define <2 x i16> @smax_smin_v2i16(
; CHECK-SAME: <2 x i16> [[X:%.*]]) {
-; CHECK-NEXT: [[MIN:%.*]] = call <2 x i16> @llvm.smin.v2i16(<2 x i16> [[X]], <2 x i16> splat (i16 127))
-; CHECK-NEXT: [[MAX:%.*]] = call <2 x i16> @llvm.smax.v2i16(<2 x i16> [[MIN]], <2 x i16> splat (i16 -128))
+; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i16> @llvm.smax.v2i16(<2 x i16> [[X]], <2 x i16> splat (i16 -128))
+; CHECK-NEXT: [[MAX:%.*]] = call <2 x i16> @llvm.smin.v2i16(<2 x i16> [[TMP1]], <2 x i16> splat (i16 127))
; CHECK-NEXT: ret <2 x i16> [[MAX]]
;
%min = call <2 x i16> @llvm.smin.v2i16(<2 x i16> %x, <2 x i16> splat (i16 127))
@@ -140,8 +140,8 @@ define <2 x i16> @smax_smin_v2i16(<2 x i16> %x) {
define <2 x i16> @umax_umin_v2i16(<2 x i16> %x) {
; CHECK-LABEL: define <2 x i16> @umax_umin_v2i16(
; CHECK-SAME: <2 x i16> [[X:%.*]]) {
-; CHECK-NEXT: [[MIN:%.*]] = call <2 x i16> @llvm.umin.v2i16(<2 x i16> [[X]], <2 x i16> splat (i16 255))
-; CHECK-NEXT: [[MAX:%.*]] = call <2 x i16> @llvm.umax.v2i16(<2 x i16> [[MIN]], <2 x i16> splat (i16 127))
+; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i16> @llvm.umax.v2i16(<2 x i16> [[X]], <2 x i16> splat (i16 127))
+; CHECK-NEXT: [[MAX:%.*]] = call <2 x i16> @llvm.umin.v2i16(<2 x i16> [[TMP1]], <2 x i16> splat (i16 255))
; CHECK-NEXT: ret <2 x i16> [[MAX]]
;
%min = call <2 x i16> @llvm.umin.v2i16(<2 x i16> %x, <2 x i16> splat (i16 255))
@@ -251,8 +251,7 @@ define i16 @umax_umin_i16_limits(i16 %x) {
define i16 @min_smax_smin_nested(i16 %x) {
; CHECK-LABEL: define i16 @min_smax_smin_nested(
; CHECK-SAME: i16 [[X:%.*]]) {
-; CHECK-NEXT: [[MIN1:%.*]] = call i16 @llvm.smin.i16(i16 [[X]], i16 255)
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.smax.i16(i16 [[MIN1]], i16 -128)
+; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.smax.i16(i16 [[X]], i16 -128)
; CHECK-NEXT: [[MIN2:%.*]] = call i16 @llvm.smin.i16(i16 [[TMP1]], i16 127)
; CHECK-NEXT: ret i16 [[MIN2]]
;
@@ -265,8 +264,7 @@ define i16 @min_smax_smin_nested(i16 %x) {
define i16 @umax_umin_nested(i16 %x) {
; CHECK-LABEL: define i16 @umax_umin_nested(
; CHECK-SAME: i16 [[X:%.*]]) {
-; CHECK-NEXT: [[MIN1:%.*]] = call i16 @llvm.umin.i16(i16 [[X]], i16 255)
-; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[MIN1]], i16 63)
+; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[X]], i16 63)
; CHECK-NEXT: [[MIN2:%.*]] = call i16 @llvm.umin.i16(i16 [[MAX]], i16 127)
; CHECK-NEXT: ret i16 [[MIN2]]
;
diff --git a/llvm/test/Transforms/InstCombine/max_known_bits.ll b/llvm/test/Transforms/InstCombine/max_known_bits.ll
index 3eb53b32efecc..162abf0efb7cc 100644
--- a/llvm/test/Transforms/InstCombine/max_known_bits.ll
+++ b/llvm/test/Transforms/InstCombine/max_known_bits.ll
@@ -35,9 +35,9 @@ define i16 @min_max_clamp(i16 %x) {
; Same as above with min/max reversed.
define i16 @min_max_clamp_2(i16 %x) {
; CHECK-LABEL: @min_max_clamp_2(
-; CHECK-NEXT: [[B:%.*]] = call i16 @llvm.smin.i16(i16 [[X:%.*]], i16 2047)
-; CHECK-NEXT: [[D:%.*]] = call i16 @llvm.smax.i16(i16 [[B]], i16 -2048)
-; CHECK-NEXT: [[E:%.*]] = add nsw i16 [[D]], 1
+; CHECK-NEXT: [[D:%.*]] = call i16 @llvm.smax.i16(i16 [[B:%.*]], i16 -2048)
+; CHECK-NEXT: [[D1:%.*]] = call i16 @llvm.smin.i16(i16 [[D]], i16 2047)
+; CHECK-NEXT: [[E:%.*]] = add nsw i16 [[D1]], 1
; CHECK-NEXT: ret i16 [[E]]
;
%a = icmp slt i16 %x, 2047
@@ -71,9 +71,9 @@ define i32 @min_max_clamp_3(i16 %x) {
; Same as above with min/max order reversed
define i32 @min_max_clamp_4(i16 %x) {
; CHECK-LABEL: @min_max_clamp_4(
-; CHECK-NEXT: [[B:%.*]] = call i16 @llvm.smin.i16(i16 [[X:%.*]], i16 2047)
-; CHECK-NEXT: [[D:%.*]] = call i16 @llvm.smax.i16(i16 [[B]], i16 -2048)
-; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[D]] to i32
+; CHECK-NEXT: [[D:%.*]] = call i16 @llvm.smax.i16(i16 [[B:%.*]], i16 -2048)
+; CHECK-NEXT: [[D1:%.*]] = call i16 @llvm.smin.i16(i16 [[D]], i16 2047)
+; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[D1]] to i32
; CHECK-NEXT: ret i32 [[TMP1]]
;
%a = icmp slt i16 %x, 2047
@@ -106,9 +106,9 @@ define i16 @min_max_clamp_intrinsic(i16 %x) {
define i16 @min_max_clamp_intrinsic_2(i16 %x) {
; CHECK-LABEL: @min_max_clamp_intrinsic_2(
-; CHECK-NEXT: [[A:%.*]] = call i16 @llvm.smin.i16(i16 [[X:%.*]], i16 2047)
-; CHECK-NEXT: [[B:%.*]] = call i16 @llvm.smax.i16(i16 [[A]], i16 -2048)
-; CHECK-NEXT: [[C:%.*]] = add nsw i16 [[B]], 1
+; CHECK-NEXT: [[B:%.*]] = call i16 @llvm.smax.i16(i16 [[A:%.*]], i16 -2048)
+; CHECK-NEXT: [[B1:%.*]] = call i16 @llvm.smin.i16(i16 [[B]], i16 2047)
+; CHECK-NEXT: [[C:%.*]] = add nsw i16 [[B1]], 1
; CHECK-NEXT: ret i16 [[C]]
;
%a = call i16 @llvm.smin.i16(i16 %x, i16 2047)
@@ -134,9 +134,9 @@ define i32 @min_max_clamp_intrinsic_3(i16 %x) {
define i32 @min_max_clamp_intrinsic_4(i16 %x) {
; CHECK-LABEL: @min_max_clamp_intrinsic_4(
-; CHECK-NEXT: [[A:%.*]] = call i16 @llvm.smin.i16(i16 [[X:%.*]], i16 2047)
-; CHECK-NEXT: [[B:%.*]] = call i16 @llvm.smax.i16(i16 [[A]], i16 -2048)
-; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[B]] to i32
+; CHECK-NEXT: [[B:%.*]] = call i16 @llvm.smax.i16(i16 [[A:%.*]], i16 -2048)
+; CHECK-NEXT: [[B1:%.*]] = call i16 @llvm.smin.i16(i16 [[B]], i16 2047)
+; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[B1]] to i32
; CHECK-NEXT: ret i32 [[TMP1]]
;
%a = call i16 @llvm.smin.i16(i16 %x, i16 2047)
diff --git a/llvm/test/Transforms/InstCombine/minmax-fold.ll b/llvm/test/Transforms/InstCombine/minmax-fold.ll
index 4d66e261c649c..cd376b74fb36c 100644
--- a/llvm/test/Transforms/InstCombine/minmax-fold.ll
+++ b/llvm/test/Transforms/InstCombine/minmax-fold.ll
@@ -346,9 +346,9 @@ define i32 @test75(i32 %x) {
define i32 @clamp_signed1(i32 %x) {
; CHECK-LABEL: @clamp_signed1(
-; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255)
-; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 15)
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN:%.*]], i32 15)
+; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.smin.i32(i32 [[R]], i32 255)
+; CHECK-NEXT: ret i32 [[R1]]
;
%cmp2 = icmp slt i32 %x, 255
%min = select i1 %cmp2, i32 %x, i32 255
@@ -376,9 +376,9 @@ define i32 @clamp_signed2(i32 %x) {
define i32 @clamp_signed3(i32 %x) {
; CHECK-LABEL: @clamp_signed3(
-; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255)
-; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 15)
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN:%.*]], i32 15)
+; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.smin.i32(i32 [[R]], i32 255)
+; CHECK-NEXT: ret i32 [[R1]]
;
%cmp2 = icmp slt i32 %x, 255
%min = select i1 %cmp2, i32 %x, i32 255
@@ -406,9 +406,9 @@ define i32 @clamp_signed4(i32 %x) {
define i32 @clamp_unsigned1(i32 %x) {
; CHECK-LABEL: @clamp_unsigned1(
-; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 255)
-; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[MIN]], i32 15)
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[MIN:%.*]], i32 15)
+; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.umin.i32(i32 [[R]], i32 255)
+; CHECK-NEXT: ret i32 [[R1]]
;
%cmp2 = icmp ult i32 %x, 255
%min = select i1 %cmp2, i32 %x, i32 255
@@ -436,9 +436,9 @@ define i32 @clamp_unsigned2(i32 %x) {
define i32 @clamp_unsigned3(i32 %x) {
; CHECK-LABEL: @clamp_unsigned3(
-; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 255)
-; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[MIN]], i32 15)
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[MIN:%.*]], i32 15)
+; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.umin.i32(i32 [[R]], i32 255)
+; CHECK-NEXT: ret i32 [[R1]]
;
%cmp2 = icmp ult i32 %x, 255
%min = select i1 %cmp2, i32 %x, i32 255
@@ -467,9 +467,9 @@ define i32 @clamp_unsigned4(i32 %x) {
; (icmp sgt smin(PositiveA, B) 0) -> (icmp sgt B 0)
define i32 @clamp_check_for_no_infinite_loop1(i32 %i) {
; CHECK-LABEL: @clamp_check_for_no_infinite_loop1(
-; CHECK-NEXT: [[SEL1:%.*]] = call i32 @llvm.smin.i32(i32 [[I:%.*]], i32 255)
-; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.smax.i32(i32 [[SEL1]], i32 0)
-; CHECK-NEXT: ret i32 [[RES]]
+; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.smax.i32(i32 [[SEL1:%.*]], i32 0)
+; CHECK-NEXT: [[RES1:%.*]] = call i32 @llvm.smin.i32(i32 [[RES]], i32 255)
+; CHECK-NEXT: ret i32 [[RES1]]
;
%cmp1 = icmp slt i32 %i, 255
%sel1 = select i1 %cmp1, i32 %i, i32 255
@@ -1429,8 +1429,8 @@ define i8 @PR46271(<2 x i8> %x) {
define i32 @twoway_clamp_lt(i32 %num) {
; CHECK-LABEL: @twoway_clamp_lt(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[NUM:%.*]], 13767
-; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP0]], i32 13768, i32 13767
+; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[NUM:%.*]], 13768
+; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP0]], i32 13767, i32 13768
; CHECK-NEXT: ret i32 [[R]]
;
entry:
diff --git a/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll b/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll
index 0b7127f82b612..9a8608da9fd5b 100644
--- a/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll
+++ b/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll
@@ -774,8 +774,8 @@ define i8 @clamp_two_vals_smax_smin(i8 %x) {
define <3 x i8> @clamp_two_vals_smin_smax(<3 x i8> %x) {
; CHECK-LABEL: @clamp_two_vals_smin_smax(
-; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <3 x i8> [[X:%.*]], splat (i8 41)
-; CHECK-NEXT: [[R:%.*]] = select <3 x i1> [[TMP1]], <3 x i8> splat (i8 42), <3 x i8> splat (i8 41)
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <3 x i8> [[X:%.*]], splat (i8 42)
+; CHECK-NEXT: [[R:%.*]] = select <3 x i1> [[TMP1]], <3 x i8> splat (i8 41), <3 x i8> splat (i8 42)
; CHECK-NEXT: ret <3 x i8> [[R]]
;
%m = call <3 x i8> @llvm.smin.v3i8(<3 x i8> %x, <3 x i8> <i8 42, i8 42, i8 42>)
@@ -796,8 +796,8 @@ define i8 @clamp_two_vals_umax_umin(i8 %x) {
define i8 @clamp_two_vals_umin_umax(i8 %x) {
; CHECK-LABEL: @clamp_two_vals_umin_umax(
-; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], 41
-; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i8 42, i8 41
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[X:%.*]], 42
+; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i8 41, i8 42
; CHECK-NEXT: ret i8 [[R]]
;
%m = call i8 @llvm.umin.i8(i8 %x, i8 42)
@@ -2192,9 +2192,9 @@ define i8 @umin_umin_reassoc_constants(i8 %x) {
define i8 @smin_smax_reassoc_constants(i8 %x) {
; CHECK-LABEL: @smin_smax_reassoc_constants(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 97)
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[M1]], i8 -3)
-; CHECK-NEXT: ret i8 [[M2]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[M1:%.*]], i8 -3)
+; CHECK-NEXT: [[M3:%.*]] = call i8 @llvm.smin.i8(i8 [[M2]], i8 97)
+; CHECK-NEXT: ret i8 [[M3]]
;
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 97)
%m2 = call i8 @llvm.smax.i8(i8 %m1, i8 -3)
diff --git a/llvm/test/Transforms/InstCombine/sadd_sat.ll b/llvm/test/Transforms/InstCombine/sadd_sat.ll
index d27e7aa28d62c..6afb77d975b8c 100644
--- a/llvm/test/Transforms/InstCombine/sadd_sat.ll
+++ b/llvm/test/Transforms/InstCombine/sadd_sat.ll
@@ -77,8 +77,8 @@ define i32 @smul_sat32(i32 %a, i32 %b) {
; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
; CHECK-NEXT: [[ADD:%.*]] = mul nsw i64 [[CONV1]], [[CONV]]
-; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647)
-; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648)
+; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.smax.i64(i64 [[ADD]], i64 -2147483648)
+; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP0]], i64 2147483647)
; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32
; CHECK-NEXT: ret i32 [[CONV7]]
;
@@ -100,8 +100,8 @@ define i32 @smul_sat32_mm(i32 %a, i32 %b) {
; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
; CHECK-NEXT: [[ADD:%.*]] = mul nsw i64 [[CONV1]], [[CONV]]
-; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647)
-; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648)
+; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.smax.i64(i64 [[ADD]], i64 -2147483648)
+; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP0]], i64 2147483647)
; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32
; CHECK-NEXT: ret i32 [[CONV7]]
;
@@ -293,8 +293,8 @@ define signext i4 @sadd_sat4(i4 signext %a, i4 signext %b) {
; CHECK-NEXT: [[CONV:%.*]] = sext i4 [[A:%.*]] to i32
; CHECK-NEXT: [[CONV1:%.*]] = sext i4 [[B:%.*]] to i32
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]]
-; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i32 @llvm.smin.i32(i32 [[ADD]], i32 7)
-; CHECK-NEXT: [[SPEC_STORE_SELECT10:%.*]] = call i32 @llvm.smax.i32(i32 [[SPEC_STORE_SELECT]], i32 -8)
+; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.smax.i32(i32 [[ADD]], i32 -8)
+; CHECK-NEXT: [[SPEC_STORE_SELECT10:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP0]], i32 7)
; CHECK-NEXT: [[CONV9:%.*]] = trunc nsw i32 [[SPEC_STORE_SELECT10]] to i4
; CHECK-NEXT: ret i4 [[CONV9]]
;
@@ -316,8 +316,8 @@ define signext i4 @ssub_sat4(i4 signext %a, i4 signext %b) {
; CHECK-NEXT: [[CONV:%.*]] = sext i4 [[A:%.*]] to i32
; CHECK-NEXT: [[CONV1:%.*]] = sext i4 [[B:%.*]] to i32
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV1]]
-; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i32 @llvm.smin.i32(i32 [[SUB]], i32 7)
-; CHECK-NEXT: [[SPEC_STORE_SELECT10:%.*]] = call i32 @llvm.smax.i32(i32 [[SPEC_STORE_SELECT]], i32 -8)
+; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.smax.i32(i32 [[SUB]], i32 -8)
+; CHECK-NEXT: [[SPEC_STORE_SELECT10:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP0]], i32 7)
; CHECK-NEXT: [[CONV9:%.*]] = trunc nsw i32 [[SPEC_STORE_SELECT10]] to i4
; CHECK-NEXT: ret i4 [[CONV9]]
;
@@ -405,8 +405,8 @@ define <4 x i32> @sadd_satv4i4(<4 x i32> %a, <4 x i32> %b) {
; CHECK-LABEL: @sadd_satv4i4(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ADD:%.*]] = add <4 x i32> [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call <4 x i32> @llvm.smin.v4i32(<4 x i32> [[ADD]], <4 x i32> splat (i32 15))
-; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call <4 x i32> @llvm.smax.v4i32(<4 x i32> [[SPEC_STORE_SELECT]], <4 x i32> splat (i32 -16))
+; CHECK-NEXT: [[TMP0:%.*]] = call <4 x i32> @llvm.smax.v4i32(<4 x i32> [[ADD]], <4 x i32> splat (i32 -16))
+; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call <4 x i32> @llvm.smin.v4i32(<4 x i32> [[TMP0]], <4 x i32> splat (i32 15))
; CHECK-NEXT: ret <4 x i32> [[SPEC_STORE_SELECT8]]
;
entry:
@@ -422,8 +422,8 @@ define <4 x i32> @ssub_satv4i4(<4 x i32> %a, <4 x i32> %b) {
; CHECK-LABEL: @ssub_satv4i4(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ADD:%.*]] = sub <4 x i32> [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call <4 x i32> @llvm.smin.v4i32(<4 x i32> [[ADD]], <4 x i32> splat (i32 15))
-; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call <4 x i32> @llvm.smax.v4i32(<4 x i32> [[SPEC_STORE_SELECT]], <4 x i32> splat (i32 -16))
+; CHECK-NEXT: [[TMP0:%.*]] = call <4 x i32> @llvm.smax.v4i32(<4 x i32> [[ADD]], <4 x i32> splat (i32 -16))
+; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call <4 x i32> @llvm.smin.v4i32(<4 x i32> [[TMP0]], <4 x i32> splat (i32 15))
; CHECK-NEXT: ret <4 x i32> [[SPEC_STORE_SELECT8]]
;
entry:
@@ -511,8 +511,8 @@ define i32 @sadd_sat32_extrause_3(i32 %a, i32 %b) {
; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
-; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647)
-; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648)
+; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.smax.i64(i64 [[ADD]], i64 -2147483648)
+; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP0]], i64 2147483647)
; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32
; CHECK-NEXT: call void @use64(i64 [[ADD]])
; CHECK-NEXT: ret i32 [[CONV7]]
@@ -536,8 +536,8 @@ define i32 @sadd_sat32_extrause_3_mm(i32 %a, i32 %b) {
; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
-; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 2147483647)
-; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -2147483648)
+; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.smax.i64(i64 [[ADD]], i64 -2147483648)
+; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP0]], i64 2147483647)
; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32
; CHECK-NEXT: call void @use64(i64 [[ADD]])
; CHECK-NEXT: ret i32 [[CONV7]]
@@ -559,8 +559,8 @@ define i32 @sadd_sat32_trunc(i32 %a, i32 %b) {
; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64
; CHECK-NEXT: [[CONV1:%.*]] = sext i32 [[B:%.*]] to i64
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV1]], [[CONV]]
-; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i64 @llvm.smin.i64(i64 [[ADD]], i64 32767)
-; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smax.i64(i64 [[SPEC_STORE_SELECT]], i64 -32768)
+; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.smax.i64(i64 [[ADD]], i64 -32768)
+; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP0]], i64 32767)
; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw i64 [[SPEC_STORE_SELECT8]] to i32
; CHECK-NEXT: ret i32 [[CONV7]]
;
@@ -601,8 +601,8 @@ define i8 @sadd_sat8_ext8(i8 %a, i16 %b) {
; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[A:%.*]] to i32
; CHECK-NEXT: [[CONV1:%.*]] = sext i16 [[B:%.*]] to i32
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV1]], [[CONV]]
-; CHECK-NEXT: [[SPEC_STORE_SELECT:%.*]] = call i32 @llvm.smin.i32(i32 [[ADD]], i32 127)
-; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i32 @llvm.smax.i32(i32 [[SPEC_STORE_SELECT]], i32 -128)
+; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.smax.i32(i32 [[ADD]], i32 -128)
+; CHECK-NEXT: [[SPEC_STORE_SELECT8:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP0]], i32 127)
; CHECK-NEXT: [[CONV7:%.*]] = trunc nsw i32 [[SPEC_STORE_SELECT8]] to i8
; CHECK-NEXT: ret i8 [[CONV7]]
;
diff --git a/llvm/test/Transforms/InstCombine/select-min-max.ll b/llvm/test/Transforms/InstCombine/select-min-max.ll
index 0430fcd5ad370..99906620f8df2 100644
--- a/llvm/test/Transforms/InstCombine/select-min-max.ll
+++ b/llvm/test/Transforms/InstCombine/select-min-max.ll
@@ -216,8 +216,8 @@ define i32 @smax_smin(i32 %x) {
define i32 @smin_smax(i32 %x) {
; CHECK-LABEL: @smin_smax(
-; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -2
-; CHECK-NEXT: [[S:%.*]] = select i1 [[TMP1]], i32 -1, i32 -2
+; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -1
+; CHECK-NEXT: [[S:%.*]] = select i1 [[TMP1]], i32 -2, i32 -1
; CHECK-NEXT: ret i32 [[S]]
;
%m = call i32 @llvm.smin.i32(i32 %x, i32 -1)
@@ -240,8 +240,8 @@ define i8 @umax_umin(i8 %x) {
define i8 @umin_umax(i8 %x) {
; CHECK-LABEL: @umin_umax(
-; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], 126
-; CHECK-NEXT: [[S:%.*]] = select i1 [[TMP1]], i8 127, i8 126
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[X:%.*]], 127
+; CHECK-NEXT: [[S:%.*]] = select i1 [[TMP1]], i8 126, i8 127
; CHECK-NEXT: ret i8 [[S]]
;
%m = call i8 @llvm.umin.i8(i8 %x, i8 127)
>From c9ff093508c29b292aaa8ea90b1b37ae601afc87 Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Tue, 22 Apr 2025 22:09:33 +0800
Subject: [PATCH 3/3] naming
---
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 7e10638cd6e29..844e18dd7d8c5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1927,7 +1927,7 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
// smax(smin(X, MinC), MaxC) -> smin(smax(X, MaxC), MinC) if MinC s>= MaxC
// umax(umin(X, MinC), MaxC) -> umin(umax(X, MaxC), MinC) if MinC u>= MaxC
const APInt *MinC, *MaxC;
- auto CreateTransposedMaxMin = [&](bool IsSigned) {
+ auto CreateCanonicalClampForm = [&](bool IsSigned) {
auto MaxIID = IsSigned ? Intrinsic::smax : Intrinsic::umax;
auto MinIID = IsSigned ? Intrinsic::smin : Intrinsic::umin;
Value *NewMax = Builder.CreateBinaryIntrinsic(
@@ -1940,12 +1940,12 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
match(I0, m_OneUse(m_Intrinsic<Intrinsic::smin>(m_Value(X),
m_APInt(MinC)))) &&
match(I1, m_APInt(MaxC)) && MinC->sgt(*MaxC))
- return CreateTransposedMaxMin(true);
+ return CreateCanonicalClampForm(true);
if (IID == Intrinsic::umax &&
match(I0, m_OneUse(m_Intrinsic<Intrinsic::umin>(m_Value(X),
m_APInt(MinC)))) &&
match(I1, m_APInt(MaxC)) && MinC->ugt(*MaxC))
- return CreateTransposedMaxMin(false);
+ return CreateCanonicalClampForm(false);
// umin(i1 X, i1 Y) -> and i1 X, Y
// smax(i1 X, i1 Y) -> and i1 X, Y
More information about the llvm-commits
mailing list