[InstCombine] Teach SimplifyDemandedVectorElts how to handle ConstantVector select masks with ConstantExpr elements (PR24922)

If the mask of a select instruction is a ConstantVector, method
SimplifyDemandedVectorElts iterates over the mask elements to identify which
values are selected from the select inputs.

Before this patch, method SimplifyDemandedVectorElts always used method
Constant::isNullValue() to check if a value in the mask was zero. Unfortunately
that method always returns false when called on a ConstantExpr.

This patch fixes the problem in SimplifyDemandedVectorElts by adding an explicit
check for ConstantExpr values. Now, if a value in the mask is a ConstantExpr, we
avoid calling isNullValue() on it.

Fixes PR24922.

Differential Revision: http://reviews.llvm.org/D13219


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249390 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrea Di Biagio 2015-10-06 10:34:53 +00:00
parent c06b5e8aab
commit b0c38394ff
2 changed files with 20 additions and 1 deletions

View File

@ -1057,7 +1057,13 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts,
APInt LeftDemanded(DemandedElts), RightDemanded(DemandedElts);
if (ConstantVector* CV = dyn_cast<ConstantVector>(I->getOperand(0))) {
for (unsigned i = 0; i < VWidth; i++) {
if (CV->getAggregateElement(i)->isNullValue())
Constant *CElt = CV->getAggregateElement(i);
// Method isNullValue always returns false when called on a
// ConstantExpr. If CElt is a ConstantExpr then skip it in order to
// to avoid propagating incorrect information.
if (isa<ConstantExpr>(CElt))
continue;
if (CElt->isNullValue())
LeftDemanded.clearBit(i);
else
RightDemanded.clearBit(i);

View File

@ -253,3 +253,16 @@ define <4 x double> @test_vpermilvar_pd_256_zero(<4 x double> %v) {
%a = tail call <4 x double> @llvm.x86.avx.vpermilvar.pd.256(<4 x double> %v, <4 x i64> zeroinitializer)
ret <4 x double> %a
}
define <2 x i64> @PR24922(<2 x i64> %v) {
; CHECK-LABEL: @PR24922
; CHECK: select <2 x i1>
;
; Check that instcombine doesn't wrongly fold the select statement into a
; ret <2 x i64> %v
;
; FIXME: We should be able to simplify the ConstantExpr in the select mask.
entry:
%result = select <2 x i1> <i1 icmp eq (i64 extractelement (<2 x i64> bitcast (<4 x i32> <i32 15, i32 15, i32 15, i32 15> to <2 x i64>), i64 0), i64 0), i1 true>, <2 x i64> %v, <2 x i64> zeroinitializer
ret <2 x i64> %result
}