@@ -651,7 +651,7 @@ class NewGVN {
651
651
BitVector TouchedInstructions;
652
652
653
653
DenseMap<const BasicBlock *, std::pair<unsigned , unsigned >> BlockInstRange;
654
- mutable DenseMap<const IntrinsicInst *, const Value *> PredicateSwapChoice;
654
+ mutable DenseMap<const BitCastInst *, const Value *> PredicateSwapChoice;
655
655
656
656
#ifndef NDEBUG
657
657
// Debugging for how many times each block and instruction got processed.
@@ -819,7 +819,7 @@ class NewGVN {
819
819
BasicBlock *PHIBlock) const ;
820
820
const Expression *performSymbolicAggrValueEvaluation (Instruction *) const ;
821
821
ExprResult performSymbolicCmpEvaluation (Instruction *) const ;
822
- ExprResult performSymbolicPredicateInfoEvaluation (IntrinsicInst *) const ;
822
+ ExprResult performSymbolicPredicateInfoEvaluation (BitCastInst *) const ;
823
823
824
824
// Congruence finding.
825
825
bool someEquivalentDominates (const Instruction *, const Instruction *) const ;
@@ -841,7 +841,7 @@ class NewGVN {
841
841
unsigned int getRank (const Value *) const ;
842
842
bool shouldSwapOperands (const Value *, const Value *) const ;
843
843
bool shouldSwapOperandsForPredicate (const Value *, const Value *,
844
- const IntrinsicInst *I) const ;
844
+ const BitCastInst *I) const ;
845
845
846
846
// Reachability handling.
847
847
void updateReachableEdge (BasicBlock *, BasicBlock *);
@@ -1013,9 +1013,9 @@ void NewGVN::deleteExpression(const Expression *E) const {
1013
1013
1014
1014
// If V is a predicateinfo copy, get the thing it is a copy of.
1015
1015
static Value *getCopyOf (const Value *V) {
1016
- if (auto *II = dyn_cast<IntrinsicInst >(V))
1017
- if (II-> getIntrinsicID () == Intrinsic::ssa_copy )
1018
- return II ->getOperand (0 );
1016
+ if (auto *BC = dyn_cast<BitCastInst >(V))
1017
+ if (BC-> getType () == BC-> getOperand ( 0 )-> getType () )
1018
+ return BC ->getOperand (0 );
1019
1019
return nullptr ;
1020
1020
}
1021
1021
@@ -1604,7 +1604,7 @@ const Expression *NewGVN::performSymbolicLoadEvaluation(Instruction *I) const {
1604
1604
}
1605
1605
1606
1606
NewGVN::ExprResult
1607
- NewGVN::performSymbolicPredicateInfoEvaluation (IntrinsicInst *I) const {
1607
+ NewGVN::performSymbolicPredicateInfoEvaluation (BitCastInst *I) const {
1608
1608
auto *PI = PredInfo->getPredicateInfoFor (I);
1609
1609
if (!PI)
1610
1610
return ExprResult::none ();
@@ -1647,13 +1647,8 @@ NewGVN::performSymbolicPredicateInfoEvaluation(IntrinsicInst *I) const {
1647
1647
NewGVN::ExprResult NewGVN::performSymbolicCallEvaluation (Instruction *I) const {
1648
1648
auto *CI = cast<CallInst>(I);
1649
1649
if (auto *II = dyn_cast<IntrinsicInst>(I)) {
1650
- // Intrinsics with the returned attribute are copies of arguments.
1651
- if (auto *ReturnedValue = II->getReturnedArgOperand ()) {
1652
- if (II->getIntrinsicID () == Intrinsic::ssa_copy)
1653
- if (auto Res = performSymbolicPredicateInfoEvaluation (II))
1654
- return Res;
1650
+ if (auto *ReturnedValue = II->getReturnedArgOperand ())
1655
1651
return ExprResult::some (createVariableOrConstant (ReturnedValue));
1656
- }
1657
1652
}
1658
1653
1659
1654
// FIXME: Currently the calls which may access the thread id may
@@ -2032,6 +2027,12 @@ NewGVN::performSymbolicEvaluation(Instruction *I,
2032
2027
E = performSymbolicLoadEvaluation (I);
2033
2028
break ;
2034
2029
case Instruction::BitCast:
2030
+ // Intrinsics with the returned attribute are copies of arguments.
2031
+ if (I->getType () == I->getOperand (0 )->getType ())
2032
+ if (auto Res =
2033
+ performSymbolicPredicateInfoEvaluation (cast<BitCastInst>(I)))
2034
+ return Res;
2035
+ [[fallthrough]];
2035
2036
case Instruction::AddrSpaceCast:
2036
2037
case Instruction::Freeze:
2037
2038
return createExpression (I);
@@ -4075,8 +4076,7 @@ bool NewGVN::eliminateInstructions(Function &F) {
4075
4076
if (DominatingLeader != Def) {
4076
4077
// Even if the instruction is removed, we still need to update
4077
4078
// flags/metadata due to downstreams users of the leader.
4078
- if (!match (DefI, m_Intrinsic<Intrinsic::ssa_copy>()))
4079
- patchReplacementInstruction (DefI, DominatingLeader);
4079
+ patchReplacementInstruction (DefI, DominatingLeader);
4080
4080
4081
4081
SmallVector<DbgVariableRecord *> DVRUsers;
4082
4082
findDbgUsers (DefI, DVRUsers);
@@ -4116,10 +4116,14 @@ bool NewGVN::eliminateInstructions(Function &F) {
4116
4116
4117
4117
Value *DominatingLeader = EliminationStack.back ();
4118
4118
4119
- auto *II = dyn_cast<IntrinsicInst>(DominatingLeader);
4120
- bool isSSACopy = II && II->getIntrinsicID () == Intrinsic::ssa_copy;
4121
- if (isSSACopy)
4122
- DominatingLeader = II->getOperand (0 );
4119
+ Instruction *SSACopy = nullptr ;
4120
+ if (auto *BC = dyn_cast<BitCastInst>(DominatingLeader)) {
4121
+ if (BC->getType () == BC->getOperand (0 )->getType () &&
4122
+ PredInfo->getPredicateInfoFor (DominatingLeader)) {
4123
+ SSACopy = BC;
4124
+ DominatingLeader = BC->getOperand (0 );
4125
+ }
4126
+ }
4123
4127
4124
4128
// Don't replace our existing users with ourselves.
4125
4129
if (U->get () == DominatingLeader)
@@ -4145,12 +4149,12 @@ bool NewGVN::eliminateInstructions(Function &F) {
4145
4149
ProbablyDead.erase (cast<Instruction>(DominatingLeader));
4146
4150
// For copy instructions, we use their operand as a leader,
4147
4151
// which means we remove a user of the copy and it may become dead.
4148
- if (isSSACopy ) {
4149
- auto It = UseCounts.find (II );
4152
+ if (SSACopy ) {
4153
+ auto It = UseCounts.find (SSACopy );
4150
4154
if (It != UseCounts.end ()) {
4151
4155
unsigned &IIUseCount = It->second ;
4152
4156
if (--IIUseCount == 0 )
4153
- ProbablyDead.insert (II );
4157
+ ProbablyDead.insert (SSACopy );
4154
4158
}
4155
4159
}
4156
4160
++LeaderUseCount;
@@ -4251,7 +4255,7 @@ bool NewGVN::shouldSwapOperands(const Value *A, const Value *B) const {
4251
4255
}
4252
4256
4253
4257
bool NewGVN::shouldSwapOperandsForPredicate (const Value *A, const Value *B,
4254
- const IntrinsicInst *I) const {
4258
+ const BitCastInst *I) const {
4255
4259
if (shouldSwapOperands (A, B)) {
4256
4260
PredicateSwapChoice[I] = B;
4257
4261
return true ;
0 commit comments