[llvm] [InstCombine] Reassociate commutative binops over select/phi/minmax (PR #187493)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 22 09:35:04 PDT 2026
================
@@ -0,0 +1,178 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -passes=instcombine -S < %s | FileCheck %s
+
+define i32 @sadd_min_max_assoc(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i32 @sadd_min_max_assoc(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT: [[LHS:%.*]] = add i32 [[X]], [[Y]]
+; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[Z]], [[LHS]]
+; CHECK-NEXT: ret i32 [[TMP5]]
+;
+ %min = call i32 @llvm.smin.i32(i32 %x, i32 %y)
+ %lhs = add i32 %z, %min
+ %max = call i32 @llvm.smax.i32(i32 %x, i32 %y)
+ %ret = add i32 %lhs, %max
+ ret i32 %ret
+}
+
+define i32 @sadd_min_max_assoc_comm(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i32 @sadd_min_max_assoc_comm(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT: [[RHS:%.*]] = add i32 [[X]], [[Y]]
+; CHECK-NEXT: [[RET:%.*]] = add i32 [[Z]], [[RHS]]
+; CHECK-NEXT: ret i32 [[RET]]
+;
+ %min = call i32 @llvm.smin.i32(i32 %x, i32 %y)
+ %rhs = add i32 %z, %min
+ %max = call i32 @llvm.smax.i32(i32 %x, i32 %y)
+ %ret = add i32 %max, %rhs
+ ret i32 %ret
+}
+
+define i32 @or_min_max_assoc(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i32 @or_min_max_assoc(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT: [[LHS:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[Z]], [[LHS]]
+; CHECK-NEXT: ret i32 [[TMP5]]
+;
+ %min = call i32 @llvm.smin.i32(i32 %x, i32 %y)
+ %lhs = or i32 %z, %min
+ %max = call i32 @llvm.smax.i32(i32 %x, i32 %y)
+ %ret = or i32 %lhs, %max
+ ret i32 %ret
+}
+
+define i32 @or_disjoint_min_max_assoc(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i32 @or_disjoint_min_max_assoc(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT: [[LHS:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[Z]], [[LHS]]
+; CHECK-NEXT: ret i32 [[TMP5]]
+;
+ %min = call i32 @llvm.smin.i32(i32 %x, i32 %y)
+ %lhs = or disjoint i32 %z, %min
+ %max = call i32 @llvm.smax.i32(i32 %x, i32 %y)
+ %ret = or i32 %lhs, %max
+ ret i32 %ret
+}
+
+define i32 @smul_min_max_assoc(i32 %x, i32 %y, i32 %z) {
----------------
dtcxzyw wrote:
Another commuted case:
```
define i32 @smul_min_max_assoc1(i32 %x, i32 %y, i32 %z) {
%min = call i32 @llvm.smin.i32(i32 %x, i32 %y)
%lhs = mul i32 %min, %z
%max = call i32 @llvm.smax.i32(i32 %x, i32 %y)
%ret = mul i32 %lhs, %max
ret i32 %ret
}
```
https://github.com/llvm/llvm-project/pull/187493
More information about the llvm-commits
mailing list