1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

[Attributor] Teach AAPotentialValues about constant select conditions

There was a TODO but now we actually check if the select condition is
assumed constant and only look at the relevant operand.
This commit is contained in:
Johannes Doerfert 2021-06-10 17:13:22 -05:00
parent 18ba32676c
commit 3ea2170c4d
2 changed files with 67 additions and 13 deletions

View File

@ -7823,23 +7823,46 @@ struct AAPotentialValuesFloating : AAPotentialValuesImpl {
if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
return indicatePessimisticFixpoint();
// TODO: Use assumed simplified condition value
auto &LHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*LHS),
DepClassTy::REQUIRED);
if (!LHSAA.isValidState())
return indicatePessimisticFixpoint();
bool UsedAssumedInformation = false;
Optional<Constant *> C = A.getAssumedConstant(*SI->getCondition(), *this,
UsedAssumedInformation);
auto &RHSAA = A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*RHS),
DepClassTy::REQUIRED);
if (!RHSAA.isValidState())
return indicatePessimisticFixpoint();
// Check if we only need one operand.
bool OnlyLeft = false, OnlyRight = false;
if (C.hasValue() && *C && (*C)->isOneValue())
OnlyLeft = true;
else if (C.hasValue() && *C && (*C)->isZeroValue())
OnlyRight = true;
if (LHSAA.undefIsContained() && RHSAA.undefIsContained())
const AAPotentialValues *LHSAA = nullptr, *RHSAA = nullptr;
if (!OnlyRight) {
LHSAA = &A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*LHS),
DepClassTy::REQUIRED);
if (!LHSAA->isValidState())
return indicatePessimisticFixpoint();
}
if (!OnlyLeft) {
RHSAA = &A.getAAFor<AAPotentialValues>(*this, IRPosition::value(*RHS),
DepClassTy::REQUIRED);
if (!RHSAA->isValidState())
return indicatePessimisticFixpoint();
}
if (!LHSAA || !RHSAA) {
// select (true/false), lhs, rhs
auto *OpAA = LHSAA ? LHSAA : RHSAA;
if (OpAA->undefIsContained())
unionAssumedWithUndef();
else
unionAssumed(*OpAA);
} else if (LHSAA->undefIsContained() && RHSAA->undefIsContained()) {
// select i1 *, undef , undef => undef
unionAssumedWithUndef();
else {
unionAssumed(LHSAA);
unionAssumed(RHSAA);
} else {
unionAssumed(*LHSAA);
unionAssumed(*RHSAA);
}
return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
: ChangeStatus::CHANGED;

View File

@ -1073,6 +1073,37 @@ b:
ret i1 %cmp2
}
define i32 @test_select(i32 %c) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_select
; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @select() #[[ATTR1]]
; IS__TUNIT____-NEXT: ret i32 [[CALL]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_select
; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-NEXT: ret i32 42
;
%call = call i32 @select(i1 1, i32 42, i32 %c)
ret i32 %call
}
define internal i32 @select(i1 %a, i32 %b, i32 %c) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@select
; IS__TUNIT____-SAME: () #[[ATTR1]] {
; IS__TUNIT____-NEXT: ret i32 42
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@select
; IS__CGSCC____-SAME: () #[[ATTR1]] {
; IS__CGSCC____-NEXT: ret i32 undef
;
%s = select i1 %a, i32 %b, i32 %c
ret i32 %s
}
define i1 @icmp() {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@icmp