From 1c0c67a007bd3a90c0340b4e11d6259eec57340b Mon Sep 17 00:00:00 2001 From: Hal Finkel Date: Sun, 7 Sep 2014 21:28:34 +0000 Subject: [PATCH] Check for all known bits on ret in InstCombine From a combination of @llvm.assume calls (and perhaps through other means, such as range metadata), it is possible that all bits of a return value might be known. Previously, InstCombine did not check for this (which is understandable given assumptions of constant propagation), but means that we'd miss simple cases where assumptions are involved. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217346 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombine.h | 1 + .../InstCombine/InstructionCombining.cpp | 18 ++++++++++++++++++ test/Transforms/InstCombine/assume.ll | 12 ++++++++++++ 3 files changed, 31 insertions(+) diff --git a/lib/Transforms/InstCombine/InstCombine.h b/lib/Transforms/InstCombine/InstCombine.h index 0c3954f4c40..6c0d4e74a7a 100644 --- a/lib/Transforms/InstCombine/InstCombine.h +++ b/lib/Transforms/InstCombine/InstCombine.h @@ -232,6 +232,7 @@ public: 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); diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index e137f32db8b..a8dd1c68288 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2004,7 +2004,25 @@ Instruction *InstCombiner::visitFree(CallInst &FI) { 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 assume intrinsics 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 diff --git a/test/Transforms/InstCombine/assume.ll b/test/Transforms/InstCombine/assume.ll index 286ca1e8d77..b328fb684aa 100644 --- a/test/Transforms/InstCombine/assume.ll +++ b/test/Transforms/InstCombine/assume.ll @@ -43,6 +43,18 @@ entry: ; Function Attrs: nounwind declare void @llvm.assume(i1) #1 +define i32 @simple(i32 %a) #1 { +entry: + +; CHECK-LABEL: @simple +; CHECK: call void @llvm.assume +; CHECK: ret i32 4 + + %cmp = icmp eq i32 %a, 4 + tail call void @llvm.assume(i1 %cmp) + ret i32 %a +} + ; Function Attrs: nounwind uwtable define i32 @can1(i1 %a, i1 %b, i1 %c) { entry: