mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-20 19:42:54 +02:00
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. llvm-svn: 217346
This commit is contained in:
parent
9ede5a39dd
commit
5d195fd587
@ -232,6 +232,7 @@ public:
|
|||||||
Instruction *visitStoreInst(StoreInst &SI);
|
Instruction *visitStoreInst(StoreInst &SI);
|
||||||
Instruction *visitBranchInst(BranchInst &BI);
|
Instruction *visitBranchInst(BranchInst &BI);
|
||||||
Instruction *visitSwitchInst(SwitchInst &SI);
|
Instruction *visitSwitchInst(SwitchInst &SI);
|
||||||
|
Instruction *visitReturnInst(ReturnInst &RI);
|
||||||
Instruction *visitInsertValueInst(InsertValueInst &IV);
|
Instruction *visitInsertValueInst(InsertValueInst &IV);
|
||||||
Instruction *visitInsertElementInst(InsertElementInst &IE);
|
Instruction *visitInsertElementInst(InsertElementInst &IE);
|
||||||
Instruction *visitExtractElementInst(ExtractElementInst &EI);
|
Instruction *visitExtractElementInst(ExtractElementInst &EI);
|
||||||
|
@ -2004,7 +2004,25 @@ Instruction *InstCombiner::visitFree(CallInst &FI) {
|
|||||||
return nullptr;
|
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) {
|
Instruction *InstCombiner::visitBranchInst(BranchInst &BI) {
|
||||||
// Change br (not X), label True, label False to: br X, label False, True
|
// Change br (not X), label True, label False to: br X, label False, True
|
||||||
|
@ -43,6 +43,18 @@ entry:
|
|||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
declare void @llvm.assume(i1) #1
|
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
|
; Function Attrs: nounwind uwtable
|
||||||
define i32 @can1(i1 %a, i1 %b, i1 %c) {
|
define i32 @can1(i1 %a, i1 %b, i1 %c) {
|
||||||
entry:
|
entry:
|
||||||
|
Loading…
Reference in New Issue
Block a user