Skip to content

Commit

Permalink
[InstCombine] Fixing wrong select folding in vectors with undef eleme…
Browse files Browse the repository at this point in the history
…nts (#102244)

This PR fixes #98435.
`SimplifyDemandedVectorElts` mishandles the undef by assuming that
!isNullValue() means the condition is true.

By preventing any value that we're not certain equals 1 or 0, it avoids
having to make any particular choice by not demanding bits from a
particular branch with potentially picking a wrong value.

Proof: https://alive2.llvm.org/ce/z/r8CmEu
  • Loading branch information
jf-botto authored Aug 9, 2024
1 parent 0e12453 commit 9304af3
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 8 deletions.
11 changes: 3 additions & 8 deletions llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1735,17 +1735,12 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
APInt DemandedLHS(DemandedElts), DemandedRHS(DemandedElts);
if (auto *CV = dyn_cast<ConstantVector>(Sel->getCondition())) {
for (unsigned i = 0; i < VWidth; i++) {
// isNullValue() always returns false when called on a ConstantExpr.
// Skip constant expressions to avoid propagating incorrect information.
Constant *CElt = CV->getAggregateElement(i);
if (isa<ConstantExpr>(CElt))
continue;
// TODO: If a select condition element is undef, we can demand from
// either side. If one side is known undef, choosing that side would
// propagate undef.

// isNullValue() always returns false when called on a ConstantExpr.
if (CElt->isNullValue())
DemandedLHS.clearBit(i);
else
else if (CElt->isOneValue())
DemandedRHS.clearBit(i);
}
}
Expand Down
12 changes: 12 additions & 0 deletions llvm/test/Transforms/InstCombine/pr98435.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes=instcombine < %s 2>&1 | FileCheck %s

define <2 x i1> @pr98435(<2 x i1> %val) {
; CHECK-LABEL: define <2 x i1> @pr98435(
; CHECK-SAME: <2 x i1> [[VAL:%.*]]) {
; CHECK-NEXT: [[VAL1:%.*]] = select <2 x i1> <i1 undef, i1 true>, <2 x i1> <i1 true, i1 true>, <2 x i1> [[VAL]]
; CHECK-NEXT: ret <2 x i1> [[VAL1]]
;
%val1 = select <2 x i1> <i1 undef, i1 true>, <2 x i1> <i1 true, i1 true>, <2 x i1> %val
ret <2 x i1> %val1
}

0 comments on commit 9304af3

Please sign in to comment.