Index: lib/Transforms/InstCombine/InstCombine.h =================================================================== --- lib/Transforms/InstCombine/InstCombine.h +++ lib/Transforms/InstCombine/InstCombine.h @@ -217,6 +217,7 @@ Instruction *visitStoreInst(StoreInst &SI); Instruction *visitBranchInst(BranchInst &BI); Instruction *visitSwitchInst(SwitchInst &SI); + Instruction *visitReturnInst(ReturnInst &RI); Instruction *visitInsertValueInst(InsertValueInst &IV); Instruction *visitInsertElementInst(InsertElementInst &IE); Instruction *visitExtractElementInst(ExtractElementInst &EI); Index: lib/Transforms/InstCombine/InstructionCombining.cpp =================================================================== --- lib/Transforms/InstCombine/InstructionCombining.cpp +++ lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1923,7 +1923,25 @@ return nullptr; } +Instruction *InstCombiner::visitReturnInst(ReturnInst &RI) { + if (RI.getNumOperands() == 0) // ret void + return nullptr; + + Value *ResultOp = RI.getOperand(0); + Type *VTy = ResultOp->getType(); + if (!VTy->isIntegerTy()) + return nullptr; + // There might be invariants dominating this return that completely determine + // the value. If so, constant fold it. + unsigned BitWidth = VTy->getPrimitiveSizeInBits(); + APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); + computeKnownBits(ResultOp, KnownZero, KnownOne, 0, &RI); + if ((KnownZero|KnownOne).isAllOnesValue()) + RI.setOperand(0, Constant::getIntegerValue(VTy, KnownOne)); + + return nullptr; +} Instruction *InstCombiner::visitBranchInst(BranchInst &BI) { // Change br (not X), label True, label False to: br X, label False, True Index: test/Transforms/InstCombine/invariants.ll =================================================================== --- test/Transforms/InstCombine/invariants.ll +++ test/Transforms/InstCombine/invariants.ll @@ -43,6 +43,18 @@ ; Function Attrs: nounwind declare void @llvm.invariant(i1) #1 +define i32 @simple(i32 %a) #1 { +entry: + +; CHECK-LABEL: @simple +; CHECK: call void @llvm.invariant +; CHECK: ret i32 4 + + %cmp = icmp eq i32 %a, 4 + tail call void @llvm.invariant(i1 %cmp) + ret i32 %a +} + ; Function Attrs: nounwind uwtable define i32 @bar1(i32 %a) #0 { entry: