[InstCombine] if the condition of a select may be known via assumes, eliminate the select

This is a limited solution for PR31512:
https://llvm.org/bugs/show_bug.cgi?id=31512

The motivation is that we will need to increase usage of llvm.assume and/or metadata to solve PR28430:
https://llvm.org/bugs/show_bug.cgi?id=28430

...and this kind of simplification is needed to take advantage of that extra information.

The 'not' test case would be handled by:
https://reviews.llvm.org/D28485

Differential Revision:
https://reviews.llvm.org/D28337

llvm-svn: 291915
This commit is contained in:
Sanjay Patel 2017-01-13 17:02:42 +00:00
parent 2dd68de32b
commit ee734847d0
3 changed files with 43 additions and 1 deletions

View File

@ -1450,6 +1450,20 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
}
}
// If we can compute the condition, there's no need for a select.
// Like the above fold, we are attempting to reduce compile-time cost by
// putting this fold here with limitations rather than in InstSimplify.
// The motivation for this call into value tracking is to take advantage of
// the assumption cache, so make sure that is populated.
if (!CondVal->getType()->isVectorTy() && !AC.assumptions().empty()) {
APInt KnownOne(1, 0), KnownZero(1, 0);
computeKnownBits(CondVal, KnownZero, KnownOne, 0, &SI);
if (KnownOne == 1)
return replaceInstUsesWith(SI, TrueVal);
if (KnownZero == 1)
return replaceInstUsesWith(SI, FalseVal);
}
if (Instruction *BitCastSel = foldSelectCmpBitcasts(SI, *Builder))
return BitCastSel;

View File

@ -1332,3 +1332,30 @@ define <4 x i32> @cannot_canonicalize_to_shuffle2(<4 x i32> %a, <4 x i32> %b) {
ret <4 x i32> %sel
}
declare void @llvm.assume(i1)
define i8 @assume_cond_true(i1 %cond, i8 %x, i8 %y) {
; CHECK-LABEL: @assume_cond_true(
; CHECK-NEXT: call void @llvm.assume(i1 %cond)
; CHECK-NEXT: ret i8 %x
;
call void @llvm.assume(i1 %cond)
%sel = select i1 %cond, i8 %x, i8 %y
ret i8 %sel
}
; FIXME: computeKnownBitsFromAssume() should understand the 'not' of an assumed condition.
define i8 @assume_cond_false(i1 %cond, i8 %x, i8 %y) {
; CHECK-LABEL: @assume_cond_false(
; CHECK-NEXT: [[NOTCOND:%.*]] = xor i1 %cond, true
; CHECK-NEXT: call void @llvm.assume(i1 [[NOTCOND]])
; CHECK-NEXT: [[SEL:%.*]] = select i1 %cond, i8 %x, i8 %y
; CHECK-NEXT: ret i8 [[SEL]]
;
%notcond = xor i1 %cond, true
call void @llvm.assume(i1 %notcond)
%sel = select i1 %cond, i8 %x, i8 %y
ret i8 %sel
}

View File

@ -402,7 +402,8 @@ define i32* @select_icmp_pointers(i32* %x, i32* %y) {
ret i32* %sel
}
; FIXME: If the condition is known, we don't need to select.
; If the condition is known, we don't need to select, but we're not
; doing this fold here to avoid compile-time cost.
declare void @llvm.assume(i1)