[llvm] 1eab2d6 - [Attributor] Keep complex select and PHI instructions in AAPotentialValues
Johannes Doerfert via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 7 22:59:03 PST 2022
Author: Johannes Doerfert
Date: 2022-12-07T22:57:52-08:00
New Revision: 1eab2d699e9581305f32473291e6afa47017d582
URL: https://github.com/llvm/llvm-project/commit/1eab2d699e9581305f32473291e6afa47017d582
DIFF: https://github.com/llvm/llvm-project/commit/1eab2d699e9581305f32473291e6afa47017d582.diff
LOG: [Attributor] Keep complex select and PHI instructions in AAPotentialValues
If a select or PHI instruction cannot be simplified to a single value it
is often beneficial to keep the value intact rather than looking at all
the operands. The reason is that various users require a single value
and consequently can deal with the select or PHI but not multiple
operands. Recursive calls of `Attributor::getAssumedSimplifiedValues`
will be required to take such select and PHI instructions apart.
Added:
Modified:
llvm/include/llvm/Transforms/IPO/Attributor.h
llvm/lib/Transforms/IPO/AttributorAttributes.cpp
llvm/test/Transforms/Attributor/nocapture-1.ll
llvm/test/Transforms/Attributor/returned.ll
llvm/test/Transforms/Attributor/value-simplify.ll
llvm/test/Transforms/Attributor/willreturn.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h
index 92a6439e393d..c78404e9a66d 100644
--- a/llvm/include/llvm/Transforms/IPO/Attributor.h
+++ b/llvm/include/llvm/Transforms/IPO/Attributor.h
@@ -1778,7 +1778,10 @@ struct Attributor {
/// Try to simplify \p IRP and in the scope \p S. If successful, true is
/// returned and all potential values \p IRP can take are put into \p Values.
- /// If false is returned no other information is valid.
+ /// If the result in \p Values contains select or PHI instructions it means
+ /// those could not be simplified to a single value. Recursive calls with
+ /// these instructions will yield their respective potential values. If false
+ /// is returned no other information is valid.
bool getAssumedSimplifiedValues(const IRPosition &IRP,
const AbstractAttribute *AA,
SmallVectorImpl<AA::ValueAndContext> &Values,
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 9d4c87dfbd65..00aff1537f0a 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -10345,10 +10345,20 @@ struct AAPotentialValuesFloating : AAPotentialValuesImpl {
Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
else
Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
- } else {
+ } else if (&SI == &getAssociatedValue()) {
// We could not simplify the condition, assume both values.
Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
+ } else {
+ std::optional<Value *> SimpleV = A.getAssumedSimplified(
+ IRPosition::inst(SI), *this, UsedAssumedInformation, II.S);
+ if (!SimpleV.has_value())
+ return true;
+ if (*SimpleV) {
+ addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope());
+ return true;
+ }
+ return false;
}
return true;
}
@@ -10433,16 +10443,28 @@ struct AAPotentialValuesFloating : AAPotentialValuesImpl {
return LI;
};
- LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
- for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) {
- BasicBlock *IncomingBB = PHI.getIncomingBlock(u);
- if (LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) {
- LI.AnyDead = true;
- continue;
+ if (&PHI == &getAssociatedValue()) {
+ LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
+ for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) {
+ BasicBlock *IncomingBB = PHI.getIncomingBlock(u);
+ if (LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) {
+ LI.AnyDead = true;
+ continue;
+ }
+ Worklist.push_back(
+ {{*PHI.getIncomingValue(u), IncomingBB->getTerminator()}, II.S});
}
- Worklist.push_back(
- {{*PHI.getIncomingValue(u), IncomingBB->getTerminator()}, II.S});
+ return true;
}
+
+ bool UsedAssumedInformation = false;
+ std::optional<Value *> SimpleV = A.getAssumedSimplified(
+ IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S);
+ if (!SimpleV.has_value())
+ return true;
+ if (!(*SimpleV))
+ return false;
+ addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope());
return true;
}
diff --git a/llvm/test/Transforms/Attributor/nocapture-1.ll b/llvm/test/Transforms/Attributor/nocapture-1.ll
index 2e0f702792fd..65a93dcfc44a 100644
--- a/llvm/test/Transforms/Attributor/nocapture-1.ll
+++ b/llvm/test/Transforms/Attributor/nocapture-1.ll
@@ -211,7 +211,8 @@ define i32 @nc1(i32* %q, i32* %p, i1 %b) {
; TUNIT-NEXT: e:
; TUNIT-NEXT: br label [[L:%.*]]
; TUNIT: l:
-; TUNIT-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E:%.*]] ]
+; TUNIT-NEXT: [[X:%.*]] = phi i32* [ [[P]], [[E:%.*]] ]
+; TUNIT-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ]
; TUNIT-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[P]], i32* [[Q]]
; TUNIT-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4
; TUNIT-NEXT: store i32 0, i32* [[P]], align 4
@@ -224,7 +225,8 @@ define i32 @nc1(i32* %q, i32* %p, i1 %b) {
; CGSCC-NEXT: e:
; CGSCC-NEXT: br label [[L:%.*]]
; CGSCC: l:
-; CGSCC-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E:%.*]] ]
+; CGSCC-NEXT: [[X:%.*]] = phi i32* [ [[P]], [[E:%.*]] ]
+; CGSCC-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ]
; CGSCC-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[P]], i32* [[Q]]
; CGSCC-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4
; CGSCC-NEXT: store i32 0, i32* [[P]], align 4
diff --git a/llvm/test/Transforms/Attributor/returned.ll b/llvm/test/Transforms/Attributor/returned.ll
index 555ffe113c3d..ac6509ac0b7f 100644
--- a/llvm/test/Transforms/Attributor/returned.ll
+++ b/llvm/test/Transforms/Attributor/returned.ll
@@ -105,7 +105,7 @@ define i32 @scc_r2(i32 %a, i32 %b, i32 %r) #0 {
; TUNIT-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
; TUNIT-NEXT: br label [[RETURN]]
; TUNIT: return:
-; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
+; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[R]], [[COND_END]] ]
; TUNIT-NEXT: ret i32 [[R]]
;
; CGSCC: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
@@ -140,7 +140,7 @@ define i32 @scc_r2(i32 %a, i32 %b, i32 %r) #0 {
; CGSCC-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
; CGSCC-NEXT: br label [[RETURN]]
; CGSCC: return:
-; CGSCC-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
+; CGSCC-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[R]], [[COND_END]] ]
; CGSCC-NEXT: ret i32 [[R]]
;
entry:
@@ -220,7 +220,7 @@ define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 {
; TUNIT-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
; TUNIT-NEXT: br label [[RETURN]]
; TUNIT: return:
-; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[B]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
+; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[B]], [[IF_THEN3]] ], [ [[R]], [[COND_END]] ]
; TUNIT-NEXT: ret i32 [[RETVAL_0]]
;
; CGSCC: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
@@ -256,7 +256,7 @@ define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 {
; CGSCC-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ]
; CGSCC-NEXT: br label [[RETURN]]
; CGSCC: return:
-; CGSCC-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
+; CGSCC-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[R]], [[COND_END]] ]
; CGSCC-NEXT: ret i32 [[RETVAL_0]]
;
entry:
@@ -389,7 +389,7 @@ define double* @ptr_scc_r2(double* %a, double* %b, double* %r) #0 {
; TUNIT-NEXT: [[COND:%.*]] = phi double* [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
; TUNIT-NEXT: br label [[RETURN]]
; TUNIT: return:
-; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi double* [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
+; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi double* [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[R]], [[COND_END]] ]
; TUNIT-NEXT: ret double* [[R]]
;
; CGSCC: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
@@ -424,7 +424,7 @@ define double* @ptr_scc_r2(double* %a, double* %b, double* %r) #0 {
; CGSCC-NEXT: [[COND:%.*]] = phi double* [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
; CGSCC-NEXT: br label [[RETURN]]
; CGSCC: return:
-; CGSCC-NEXT: [[RETVAL_0:%.*]] = phi double* [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
+; CGSCC-NEXT: [[RETVAL_0:%.*]] = phi double* [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[R]], [[COND_END]] ]
; CGSCC-NEXT: ret double* [[R]]
;
entry:
@@ -800,6 +800,7 @@ define double @select_and_phi(double %b) #0 {
; CHECK: if.then:
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end:
+; CHECK-NEXT: [[PHI:%.*]] = phi double [ [[B]], [[IF_THEN]] ], [ [[B]], [[ENTRY:%.*]] ]
; CHECK-NEXT: ret double [[B]]
;
entry:
@@ -838,6 +839,7 @@ define double @recursion_select_and_phi(i32 %a, double %b) #0 {
; TUNIT-NEXT: [[CALL:%.*]] = call double @recursion_select_and_phi(i32 [[DEC]], double [[B]]) #[[ATTR10]]
; TUNIT-NEXT: br label [[IF_END]]
; TUNIT: if.end:
+; TUNIT-NEXT: [[PHI:%.*]] = phi double [ [[B]], [[IF_THEN]] ], [ [[B]], [[ENTRY:%.*]] ]
; TUNIT-NEXT: ret double [[B]]
;
; CGSCC: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable
@@ -851,6 +853,7 @@ define double @recursion_select_and_phi(i32 %a, double %b) #0 {
; CGSCC-NEXT: [[CALL:%.*]] = call double @recursion_select_and_phi(i32 [[DEC]], double [[B]]) #[[ATTR7]]
; CGSCC-NEXT: br label [[IF_END]]
; CGSCC: if.end:
+; CGSCC-NEXT: [[PHI:%.*]] = phi double [ [[B]], [[IF_THEN]] ], [ [[B]], [[ENTRY:%.*]] ]
; CGSCC-NEXT: ret double [[B]]
;
entry:
diff --git a/llvm/test/Transforms/Attributor/value-simplify.ll b/llvm/test/Transforms/Attributor/value-simplify.ll
index 490b5bb7e876..99e0bdbc7b46 100644
--- a/llvm/test/Transforms/Attributor/value-simplify.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify.ll
@@ -188,12 +188,11 @@ define void @test-select-phi(i1 %c) {
; CHECK-NEXT: [[PHI_NOT_SAME:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ]
; CHECK-NEXT: [[PHI_SAME_PROP:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ]
; CHECK-NEXT: [[PHI_SAME_UNDEF:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ undef, [[IF_FALSE]] ]
-; CHECK-NEXT: [[SELECT_NOT_SAME_UNDEF:%.*]] = select i1 [[C]], i32 [[PHI_NOT_SAME]], i32 undef
; CHECK-NEXT: tail call void @use(i32 noundef 1)
; CHECK-NEXT: tail call void @use(i32 noundef [[PHI_NOT_SAME]])
; CHECK-NEXT: tail call void @use(i32 noundef 1)
; CHECK-NEXT: tail call void @use(i32 1)
-; CHECK-NEXT: tail call void @use(i32 [[SELECT_NOT_SAME_UNDEF]])
+; CHECK-NEXT: tail call void @use(i32 [[PHI_NOT_SAME]])
; CHECK-NEXT: ret void
;
%select-same = select i1 %c, i32 1, i32 1
diff --git a/llvm/test/Transforms/Attributor/willreturn.ll b/llvm/test/Transforms/Attributor/willreturn.ll
index 76675f9c8ab6..a84393c73f30 100644
--- a/llvm/test/Transforms/Attributor/willreturn.ll
+++ b/llvm/test/Transforms/Attributor/willreturn.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
-; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=14 -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
+; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=15 -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
target datalayout = "e-m:e-i54:64-f80:128-n8:16:32:64-S128"
More information about the llvm-commits
mailing list