Index: lib/Analysis/CodeMetrics.cpp =================================================================== --- lib/Analysis/CodeMetrics.cpp +++ lib/Analysis/CodeMetrics.cpp @@ -69,6 +69,7 @@ return false; case Intrinsic::dbg_declare: case Intrinsic::dbg_value: + case Intrinsic::invariant: case Intrinsic::invariant_start: case Intrinsic::invariant_end: case Intrinsic::lifetime_start: Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -1898,6 +1898,7 @@ // should be considered at least *safe* to speculate... case Intrinsic::dbg_declare: case Intrinsic::dbg_value: + case Intrinsic::invariant: return true; case Intrinsic::bswap: Index: lib/CodeGen/IntrinsicLowering.cpp =================================================================== --- lib/CodeGen/IntrinsicLowering.cpp +++ lib/CodeGen/IntrinsicLowering.cpp @@ -453,6 +453,7 @@ CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); break; + case Intrinsic::invariant: case Intrinsic::var_annotation: break; // Strip out annotate intrinsic Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -5018,6 +5018,7 @@ setValue(&I, Res); return 0; } + case Intrinsic::invariant: case Intrinsic::var_annotation: // Discard annotate attributes return 0; Index: lib/Transforms/Scalar/ADCE.cpp =================================================================== --- lib/Transforms/Scalar/ADCE.cpp +++ lib/Transforms/Scalar/ADCE.cpp @@ -23,6 +23,7 @@ #include "llvm/BasicBlock.h" #include "llvm/Instructions.h" #include "llvm/IntrinsicInst.h" +#include "llvm/Intrinsics.h" #include "llvm/Pass.h" #include "llvm/Support/CFG.h" #include "llvm/Support/InstIterator.h" @@ -49,6 +50,13 @@ char ADCE::ID = 0; INITIALIZE_PASS(ADCE, "adce", "Aggressive Dead Code Elimination", false, false) +static bool isInvariantIntrinsic(Instruction *I) { + if (IntrinsicInst *II = dyn_cast(I)) + return II->getIntrinsicID() == Intrinsic::invariant; + + return false; +} + bool ADCE::runOnFunction(Function& F) { SmallPtrSet alive; SmallVector worklist; @@ -57,6 +65,7 @@ for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) if (isa(I.getInstructionIterator()) || isa(I.getInstructionIterator()) || + isInvariantIntrinsic(I.getInstructionIterator()) || isa(I.getInstructionIterator()) || I->mayHaveSideEffects()) { alive.insert(I.getInstructionIterator()); Index: lib/Transforms/Utils/Local.cpp =================================================================== --- lib/Transforms/Utils/Local.cpp +++ lib/Transforms/Utils/Local.cpp @@ -286,6 +286,12 @@ return true; } + if (IntrinsicInst *II = dyn_cast(I)) { + // Invariants are dead if their condition is undef. + if (II->getIntrinsicID() == Intrinsic::invariant) + return isa(II->getArgOperand(0)); + } + if (!I->mayHaveSideEffects()) return true; // Special case intrinsics that "may have side effects" but can be deleted