[llvm] 2814216 - [SCEV] Recognize `x == 0 ? 0 : umin(..., x, ...) -> umin_seq(x, umin(...))`
Roman Lebedev via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 11 10:58:37 PST 2022
Author: Roman Lebedev
Date: 2022-02-11T21:58:19+03:00
New Revision: 281421693bc1fb44c98ff719c5e3d2efb9c88830
URL: https://github.com/llvm/llvm-project/commit/281421693bc1fb44c98ff719c5e3d2efb9c88830
DIFF: https://github.com/llvm/llvm-project/commit/281421693bc1fb44c98ff719c5e3d2efb9c88830.diff
LOG: [SCEV] Recognize `x == 0 ? 0 : umin(..., x, ...) -> umin_seq(x, umin(...))`
That is the canonical expansion for umin_seq,
so we really should roundtrip it.
Added:
Modified:
llvm/lib/Analysis/ScalarEvolution.cpp
llvm/test/Analysis/ScalarEvolution/logical-operations.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 84680ff6b9b3..e5a934191e04 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -5967,6 +5967,15 @@ const SCEV *ScalarEvolution::createNodeForSelectOrPHIInstWithICmpInstCond(
if (isa<SCEVConstant>(C) && cast<SCEVConstant>(C)->getAPInt().ule(1))
return getAddExpr(getUMaxExpr(X, C), Y);
}
+ // x == 0 ? 0 : umin(..., x, ...) -> umin_seq(x, umin(...))
+ if (getTypeSizeInBits(LHS->getType()) == getTypeSizeInBits(I->getType()) &&
+ isa<ConstantInt>(RHS) && cast<ConstantInt>(RHS)->isZero() &&
+ isa<ConstantInt>(TrueVal) && cast<ConstantInt>(TrueVal)->isZero()) {
+ const SCEV *X = getSCEV(LHS);
+ auto *UMin = dyn_cast<SCEVUMinExpr>(getSCEV(FalseVal));
+ if (UMin && is_contained(UMin->operands(), X))
+ return getUMinExpr(X, UMin, /*Sequential=*/true);
+ }
break;
default:
break;
diff --git a/llvm/test/Analysis/ScalarEvolution/logical-operations.ll b/llvm/test/Analysis/ScalarEvolution/logical-operations.ll
index 8f04e02f61ba..1dde49a1a6c4 100644
--- a/llvm/test/Analysis/ScalarEvolution/logical-operations.ll
+++ b/llvm/test/Analysis/ScalarEvolution/logical-operations.ll
@@ -463,7 +463,7 @@ define i32 @umin_seq_x_y(i32 %x, i32 %y) {
; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %y, i32 %x)
; CHECK-NEXT: --> (%x umin %y) U: full-set S: full-set
; CHECK-NEXT: %r = select i1 %x.is.zero, i32 0, i32 %umin
-; CHECK-NEXT: --> %r U: full-set S: full-set
+; CHECK-NEXT: --> (%x umin_seq %y) U: full-set S: full-set
; CHECK-NEXT: Determining loop execution counts for: @umin_seq_x_y
;
%umin = call i32 @llvm.umin(i32 %y, i32 %x)
@@ -568,7 +568,7 @@ define i32 @umin_seq_y_x(i32 %x, i32 %y) {
; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %x, i32 %y)
; CHECK-NEXT: --> (%x umin %y) U: full-set S: full-set
; CHECK-NEXT: %r = select i1 %x.is.zero, i32 0, i32 %umin
-; CHECK-NEXT: --> %r U: full-set S: full-set
+; CHECK-NEXT: --> (%y umin_seq %x) U: full-set S: full-set
; CHECK-NEXT: Determining loop execution counts for: @umin_seq_y_x
;
%umin = call i32 @llvm.umin(i32 %x, i32 %y)
@@ -585,7 +585,7 @@ define i32 @umin_seq_x_x_y_z(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %umin0, i32 %y)
; CHECK-NEXT: --> (%x umin %y umin %z) U: full-set S: full-set
; CHECK-NEXT: %r0 = select i1 %x.is.zero, i32 0, i32 %umin
-; CHECK-NEXT: --> %r0 U: full-set S: full-set
+; CHECK-NEXT: --> (%x umin_seq (%y umin %z)) U: full-set S: full-set
; CHECK-NEXT: %r = select i1 %x.is.zero, i32 0, i32 %r0
; CHECK-NEXT: --> %r U: full-set S: full-set
; CHECK-NEXT: Determining loop execution counts for: @umin_seq_x_x_y_z
@@ -606,7 +606,7 @@ define i32 @umin_seq_x_y_z(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %umin0, i32 %y)
; CHECK-NEXT: --> (%x umin %y umin %z) U: full-set S: full-set
; CHECK-NEXT: %r0 = select i1 %y.is.zero, i32 0, i32 %umin
-; CHECK-NEXT: --> %r0 U: full-set S: full-set
+; CHECK-NEXT: --> (%y umin_seq (%x umin %z)) U: full-set S: full-set
; CHECK-NEXT: %r = select i1 %x.is.zero, i32 0, i32 %r0
; CHECK-NEXT: --> %r U: full-set S: full-set
; CHECK-NEXT: Determining loop execution counts for: @umin_seq_x_y_z
@@ -626,11 +626,11 @@ define i32 @umin_seq_a_b_c_d(i32 %a, i32 %b, i32 %c, i32 %d) {
; CHECK-NEXT: %umin1 = call i32 @llvm.umin.i32(i32 %c, i32 %d)
; CHECK-NEXT: --> (%c umin %d) U: full-set S: full-set
; CHECK-NEXT: %r1 = select i1 %c.is.zero, i32 0, i32 %umin1
-; CHECK-NEXT: --> %r1 U: full-set S: full-set
+; CHECK-NEXT: --> (%c umin_seq %d) U: full-set S: full-set
; CHECK-NEXT: %umin0 = call i32 @llvm.umin.i32(i32 %a, i32 %b)
; CHECK-NEXT: --> (%a umin %b) U: full-set S: full-set
; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %umin0, i32 %r1)
-; CHECK-NEXT: --> (%a umin %b umin %r1) U: full-set S: full-set
+; CHECK-NEXT: --> ((%c umin_seq %d) umin %a umin %b) U: full-set S: full-set
; CHECK-NEXT: %r = select i1 %d.is.zero, i32 0, i32 %umin
; CHECK-NEXT: --> %r U: full-set S: full-set
; CHECK-NEXT: Determining loop execution counts for: @umin_seq_a_b_c_d
@@ -654,7 +654,7 @@ define i32 @select_x_or_zero_expanded(i1 %c, i32 %x) {
; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %c.splat, i32 %x)
; CHECK-NEXT: --> ((sext i1 %c to i32) umin %x) U: full-set S: full-set
; CHECK-NEXT: %r = select i1 %v0.is.zero, i32 0, i32 %umin
-; CHECK-NEXT: --> %r U: full-set S: full-set
+; CHECK-NEXT: --> ((sext i1 %c to i32) umin_seq %x) U: full-set S: full-set
; CHECK-NEXT: Determining loop execution counts for: @select_x_or_zero_expanded
;
%c.splat = sext i1 %c to i32
@@ -674,7 +674,7 @@ define i32 @select_zero_or_x_expanded(i1 %c, i32 %y) {
; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %c.splat.not, i32 %y)
; CHECK-NEXT: --> ((-1 + (-1 * (sext i1 %c to i32))<nsw>)<nsw> umin %y) U: full-set S: full-set
; CHECK-NEXT: %r = select i1 %v0.is.zero, i32 0, i32 %umin
-; CHECK-NEXT: --> %r U: full-set S: full-set
+; CHECK-NEXT: --> ((-1 + (-1 * (sext i1 %c to i32))<nsw>)<nsw> umin_seq %y) U: full-set S: full-set
; CHECK-NEXT: Determining loop execution counts for: @select_zero_or_x_expanded
;
%c.splat = sext i1 %c to i32
@@ -694,7 +694,7 @@ define i32 @select_zero_or_x_expanded2(i1 %c, i32 %y) {
; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %c.not.splat, i32 %y)
; CHECK-NEXT: --> ((sext i1 (true + %c) to i32) umin %y) U: full-set S: full-set
; CHECK-NEXT: %r = select i1 %v0.is.zero, i32 0, i32 %umin
-; CHECK-NEXT: --> %r U: full-set S: full-set
+; CHECK-NEXT: --> ((sext i1 (true + %c) to i32) umin_seq %y) U: full-set S: full-set
; CHECK-NEXT: Determining loop execution counts for: @select_zero_or_x_expanded2
;
%c.not = xor i1 %c, -1
@@ -715,9 +715,9 @@ define i32 @select_x_or_constant_expanded(i1 %c, i32 %x) {
; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %c.splat, i32 %x.off)
; CHECK-NEXT: --> ((sext i1 %c to i32) umin (-42 + %x)) U: full-set S: full-set
; CHECK-NEXT: %r.off = select i1 %v0.is.zero, i32 0, i32 %umin
-; CHECK-NEXT: --> %r.off U: full-set S: full-set
+; CHECK-NEXT: --> ((sext i1 %c to i32) umin_seq (-42 + %x)) U: full-set S: full-set
; CHECK-NEXT: %r = add i32 %r.off, 42
-; CHECK-NEXT: --> (42 + %r.off) U: full-set S: full-set
+; CHECK-NEXT: --> (42 + ((sext i1 %c to i32) umin_seq (-42 + %x))) U: full-set S: full-set
; CHECK-NEXT: Determining loop execution counts for: @select_x_or_constant_expanded
;
%c.splat = sext i1 %c to i32
@@ -741,9 +741,9 @@ define i32 @select_constant_or_y_expanded(i1 %c, i32 %y) {
; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %c.splat.not, i32 %y.off)
; CHECK-NEXT: --> ((-42 + %y) umin (-1 + (-1 * (sext i1 %c to i32))<nsw>)<nsw>) U: full-set S: full-set
; CHECK-NEXT: %r.off = select i1 %v0.is.zero, i32 0, i32 %umin
-; CHECK-NEXT: --> %r.off U: full-set S: full-set
+; CHECK-NEXT: --> ((-1 + (-1 * (sext i1 %c to i32))<nsw>)<nsw> umin_seq (-42 + %y)) U: full-set S: full-set
; CHECK-NEXT: %r = add i32 %r.off, 42
-; CHECK-NEXT: --> (42 + %r.off) U: full-set S: full-set
+; CHECK-NEXT: --> (42 + ((-1 + (-1 * (sext i1 %c to i32))<nsw>)<nsw> umin_seq (-42 + %y))) U: full-set S: full-set
; CHECK-NEXT: Determining loop execution counts for: @select_constant_or_y_expanded
;
%c.splat = sext i1 %c to i32
More information about the llvm-commits
mailing list