@@ -2016,43 +2016,43 @@ static bool markAliveBlocks(Function &F,
2016
2016
// instructions into LLVM unreachable insts. The instruction combining pass
2017
2017
// canonicalizes unreachable insts into stores to null or undef.
2018
2018
for (Instruction &I : *BB) {
2019
- // Assumptions that are known to be false are equivalent to unreachable.
2020
- // Also, if the condition is undefined, then we make the choice most
2021
- // beneficial to the optimizer, and choose that to also be unreachable.
2022
- if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
2023
- if (II->getIntrinsicID () == Intrinsic::assume) {
2024
- if (match (II->getArgOperand (0 ), m_CombineOr (m_Zero (), m_Undef ()))) {
2025
- // Don't insert a call to llvm.trap right before the unreachable.
2026
- changeToUnreachable (II, false , false , DDT);
2027
- Changed = true ;
2028
- break ;
2029
- }
2030
- }
2031
-
2032
- if (II->getIntrinsicID () == Intrinsic::experimental_guard) {
2033
- // A call to the guard intrinsic bails out of the current compilation
2034
- // unit if the predicate passed to it is false. If the predicate is a
2035
- // constant false, then we know the guard will bail out of the current
2036
- // compile unconditionally, so all code following it is dead.
2037
- //
2038
- // Note: unlike in llvm.assume, it is not "obviously profitable" for
2039
- // guards to treat `undef` as `false` since a guard on `undef` can
2040
- // still be useful for widening.
2041
- if (match (II->getArgOperand (0 ), m_Zero ()))
2042
- if (!isa<UnreachableInst>(II->getNextNode ())) {
2043
- changeToUnreachable (II->getNextNode (), /* UseLLVMTrap=*/ false ,
2044
- false , DDT);
2019
+ if (auto *CI = dyn_cast<CallInst>(&I)) {
2020
+ Value *Callee = CI->getCalledValue ();
2021
+ // Handle intrinsic calls.
2022
+ if (Function *F = dyn_cast<Function>(Callee)) {
2023
+ auto IntrinsicID = F->getIntrinsicID ();
2024
+ // Assumptions that are known to be false are equivalent to
2025
+ // unreachable. Also, if the condition is undefined, then we make the
2026
+ // choice most beneficial to the optimizer, and choose that to also be
2027
+ // unreachable.
2028
+ if (IntrinsicID == Intrinsic::assume) {
2029
+ if (match (CI->getArgOperand (0 ), m_CombineOr (m_Zero (), m_Undef ()))) {
2030
+ // Don't insert a call to llvm.trap right before the unreachable.
2031
+ changeToUnreachable (CI, false , false , DDT);
2045
2032
Changed = true ;
2046
2033
break ;
2047
2034
}
2048
- }
2049
- }
2050
-
2051
- if (auto *CI = dyn_cast<CallInst>(&I)) {
2052
- Value *Callee = CI->getCalledValue ();
2053
- if ((isa<ConstantPointerNull>(Callee) &&
2054
- !NullPointerIsDefined (CI->getFunction ())) ||
2055
- isa<UndefValue>(Callee)) {
2035
+ } else if (IntrinsicID == Intrinsic::experimental_guard) {
2036
+ // A call to the guard intrinsic bails out of the current
2037
+ // compilation unit if the predicate passed to it is false. If the
2038
+ // predicate is a constant false, then we know the guard will bail
2039
+ // out of the current compile unconditionally, so all code following
2040
+ // it is dead.
2041
+ //
2042
+ // Note: unlike in llvm.assume, it is not "obviously profitable" for
2043
+ // guards to treat `undef` as `false` since a guard on `undef` can
2044
+ // still be useful for widening.
2045
+ if (match (CI->getArgOperand (0 ), m_Zero ()))
2046
+ if (!isa<UnreachableInst>(CI->getNextNode ())) {
2047
+ changeToUnreachable (CI->getNextNode (), /* UseLLVMTrap=*/ false ,
2048
+ false , DDT);
2049
+ Changed = true ;
2050
+ break ;
2051
+ }
2052
+ }
2053
+ } else if ((isa<ConstantPointerNull>(Callee) &&
2054
+ !NullPointerIsDefined (CI->getFunction ())) ||
2055
+ isa<UndefValue>(Callee)) {
2056
2056
changeToUnreachable (CI, /* UseLLVMTrap=*/ false , false , DDT);
2057
2057
Changed = true ;
2058
2058
break ;
@@ -2068,12 +2068,11 @@ static bool markAliveBlocks(Function &F,
2068
2068
}
2069
2069
break ;
2070
2070
}
2071
- }
2071
+ } else if (auto *SI = dyn_cast<StoreInst>(&I)) {
2072
+ // Store to undef and store to null are undefined and used to signal
2073
+ // that they should be changed to unreachable by passes that can't
2074
+ // modify the CFG.
2072
2075
2073
- // Store to undef and store to null are undefined and used to signal that
2074
- // they should be changed to unreachable by passes that can't modify the
2075
- // CFG.
2076
- if (auto *SI = dyn_cast<StoreInst>(&I)) {
2077
2076
// Don't touch volatile stores.
2078
2077
if (SI->isVolatile ()) continue ;
2079
2078
0 commit comments