[llvm] e7e0834 - [SCEV] Recognize binary `or` as bit-wise `umax`
Roman Lebedev via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 10 06:46:57 PST 2022
Author: Roman Lebedev
Date: 2022-02-10T17:42:54+03:00
New Revision: e7e0834f076afaf3cde2c6c7270821084389dff8
URL: https://github.com/llvm/llvm-project/commit/e7e0834f076afaf3cde2c6c7270821084389dff8
DIFF: https://github.com/llvm/llvm-project/commit/e7e0834f076afaf3cde2c6c7270821084389dff8.diff
LOG: [SCEV] Recognize binary `or` as bit-wise `umax`
https://alive2.llvm.org/ce/z/SMEaoc
We could transparently handle wider bitwidths,
by effectively casting iN to <N x i1> and performing the `umax`
bit/element -wise, the expression will be rather large,
so let's not do that for now.
Added:
Modified:
llvm/lib/Analysis/ScalarEvolution.cpp
llvm/test/Analysis/ScalarEvolution/exact-exit-count-more-precise.ll
llvm/test/Analysis/ScalarEvolution/logical-operations.ll
llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
llvm/test/Analysis/ScalarEvolution/pr48225.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 546268b4da20f..36fa16267c5c2 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -7199,6 +7199,9 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
(SCEV::NoWrapFlags)(SCEV::FlagNUW | SCEV::FlagNSW));
}
}
+ // Binary `or` is a bit-wise `umax`.
+ if (BO->LHS->getType()->isIntegerTy(1))
+ return getUMaxExpr(getSCEV(BO->LHS), getSCEV(BO->RHS));
break;
case Instruction::Xor:
diff --git a/llvm/test/Analysis/ScalarEvolution/exact-exit-count-more-precise.ll b/llvm/test/Analysis/ScalarEvolution/exact-exit-count-more-precise.ll
index d57265bb94a3c..f33de3c7ec0f6 100644
--- a/llvm/test/Analysis/ScalarEvolution/exact-exit-count-more-precise.ll
+++ b/llvm/test/Analysis/ScalarEvolution/exact-exit-count-more-precise.ll
@@ -51,7 +51,7 @@ define void @test_or() {
; CHECK-NEXT: %B3 = add i32 %1, %2
; CHECK-NEXT: --> {(-2 + undef),+,-1}<%BB> U: full-set S: full-set Exits: -2 LoopDispositions: { %BB: Computable }
; CHECK-NEXT: %B = or i1 %C5, %C11
-; CHECK-NEXT: --> %B U: full-set S: full-set Exits: false LoopDispositions: { %BB: Variant }
+; CHECK-NEXT: --> (%C11 umax %C5) U: full-set S: full-set Exits: false LoopDispositions: { %BB: Variant }
; CHECK-NEXT: Determining loop execution counts for: @test_or
; CHECK-NEXT: Loop %BB: backedge-taken count is undef
; CHECK-NEXT: Loop %BB: max backedge-taken count is -1
diff --git a/llvm/test/Analysis/ScalarEvolution/logical-operations.ll b/llvm/test/Analysis/ScalarEvolution/logical-operations.ll
index 187c5d5e75b93..1b7c554d995ee 100644
--- a/llvm/test/Analysis/ScalarEvolution/logical-operations.ll
+++ b/llvm/test/Analysis/ScalarEvolution/logical-operations.ll
@@ -8,7 +8,7 @@ define i1 @binary_or.i1(i1 %x, i1 %y) {
; CHECK-LABEL: 'binary_or.i1'
; CHECK-NEXT: Classifying expressions for: @binary_or.i1
; CHECK-NEXT: %r = or i1 %x, %y
-; CHECK-NEXT: --> %r U: full-set S: full-set
+; CHECK-NEXT: --> (%x umax %y) U: full-set S: full-set
; CHECK-NEXT: Determining loop execution counts for: @binary_or.i1
;
%r = or i1 %x, %y
@@ -30,11 +30,11 @@ define i1 @binary_or.4ops.i1(i1 %x, i1 %y, i1 %z, i1 %a) {
; CHECK-LABEL: 'binary_or.4ops.i1'
; CHECK-NEXT: Classifying expressions for: @binary_or.4ops.i1
; CHECK-NEXT: %t0 = or i1 %x, %y
-; CHECK-NEXT: --> %t0 U: full-set S: full-set
+; CHECK-NEXT: --> (%x umax %y) U: full-set S: full-set
; CHECK-NEXT: %t1 = or i1 %z, %a
-; CHECK-NEXT: --> %t1 U: full-set S: full-set
+; CHECK-NEXT: --> (%z umax %a) U: full-set S: full-set
; CHECK-NEXT: %r = or i1 %t0, %t1
-; CHECK-NEXT: --> %r U: full-set S: full-set
+; CHECK-NEXT: --> (%x umax %y umax %z umax %a) U: full-set S: full-set
; CHECK-NEXT: Determining loop execution counts for: @binary_or.4ops.i1
;
%t0 = or i1 %x, %y
diff --git a/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll b/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
index 1a9dba0511cd2..54c5e79ef0b14 100644
--- a/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
+++ b/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
@@ -597,7 +597,7 @@ define void @test_guard_if_and_or(i32* nocapture readonly %data, i64 %count, i1
; CHECK-LABEL: 'test_guard_if_and_or'
; CHECK-NEXT: Classifying expressions for: @test_guard_if_and_or
; CHECK-NEXT: %cmp.or = or i1 %c, %cmp.ne
-; CHECK-NEXT: --> %cmp.or U: full-set S: full-set
+; CHECK-NEXT: --> (%c umax %cmp.ne) U: full-set S: full-set
; CHECK-NEXT: %cmp.and = and i1 %cmp.ult, %cmp.or
; CHECK-NEXT: --> %cmp.and U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
@@ -636,7 +636,7 @@ define void @test_guard_if_or_skip(i32* nocapture readonly %data, i64 %count) {
; CHECK-LABEL: 'test_guard_if_or_skip'
; CHECK-NEXT: Classifying expressions for: @test_guard_if_or_skip
; CHECK-NEXT: %cmp.or = or i1 %cmp.uge, %cmp.eq
-; CHECK-NEXT: --> %cmp.or U: full-set S: full-set
+; CHECK-NEXT: --> (%cmp.uge umax %cmp.eq) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %data, i64 %iv
@@ -672,7 +672,7 @@ define void @test_guard_if_or_enter(i32* nocapture readonly %data, i64 %count) {
; CHECK-LABEL: 'test_guard_if_or_enter'
; CHECK-NEXT: Classifying expressions for: @test_guard_if_or_enter
; CHECK-NEXT: %cmp.or = or i1 %cmp.uge, %cmp.eq
-; CHECK-NEXT: --> %cmp.or U: full-set S: full-set
+; CHECK-NEXT: --> (%cmp.uge umax %cmp.eq) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %data, i64 %iv
@@ -708,9 +708,9 @@ define void @test_guard_if_or_or(i32* nocapture readonly %data, i64 %count, i1 %
; CHECK-LABEL: 'test_guard_if_or_or'
; CHECK-NEXT: Classifying expressions for: @test_guard_if_or_or
; CHECK-NEXT: %cmp.or1 = or i1 %c, %cmp.eq
-; CHECK-NEXT: --> %cmp.or1 U: full-set S: full-set
+; CHECK-NEXT: --> (%c umax %cmp.eq) U: full-set S: full-set
; CHECK-NEXT: %cmp.or = or i1 %cmp.uge, %cmp.or1
-; CHECK-NEXT: --> %cmp.or U: full-set S: full-set
+; CHECK-NEXT: --> (%c umax %cmp.uge umax %cmp.eq) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %data, i64 %iv
@@ -749,7 +749,7 @@ define void @test_guard_if_or_and(i32* nocapture readonly %data, i64 %count, i1
; CHECK-NEXT: %cmp.and = and i1 %c, %cmp.eq
; CHECK-NEXT: --> %cmp.and U: full-set S: full-set
; CHECK-NEXT: %cmp.or = or i1 %cmp.uge, %cmp.and
-; CHECK-NEXT: --> %cmp.or U: full-set S: full-set
+; CHECK-NEXT: --> (%cmp.and umax %cmp.uge) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %data, i64 %iv
diff --git a/llvm/test/Analysis/ScalarEvolution/pr48225.ll b/llvm/test/Analysis/ScalarEvolution/pr48225.ll
index 6e2de25a02bc3..38e0967b4caef 100644
--- a/llvm/test/Analysis/ScalarEvolution/pr48225.ll
+++ b/llvm/test/Analysis/ScalarEvolution/pr48225.ll
@@ -64,7 +64,7 @@ define void @test_or(i1 %boolcond) {
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %inc, %backedge ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,3) S: [0,3) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %or.cond = or i1 %cond.true.on.first.iter, %cond.true.on.second.iter
-; CHECK-NEXT: --> %or.cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: --> (%cond.true.on.first.iter umax %cond.true.on.second.iter) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %inc = add nuw nsw i32 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,4) S: [1,4) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_or
More information about the llvm-commits
mailing list