Skip to content

Commit 964df09

Browse files
committed
[ValueTracking] Support non-constant idx for computeKnownBits of insertelement
Its same logic as before, we just need to intersect what we know about the new Elt and the entire pre-existing Vec. Closes #87707
1 parent 3a23675 commit 964df09

File tree

2 files changed

+12
-18
lines changed

2 files changed

+12
-18
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1727,26 +1727,25 @@ static void computeKnownBitsFromOperator(const Operator *I,
17271727
const Value *Vec = I->getOperand(0);
17281728
const Value *Elt = I->getOperand(1);
17291729
auto *CIdx = dyn_cast<ConstantInt>(I->getOperand(2));
1730-
// Early out if the index is non-constant or out-of-range.
17311730
unsigned NumElts = DemandedElts.getBitWidth();
1732-
if (!CIdx || CIdx->getValue().uge(NumElts)) {
1733-
Known.resetAll();
1734-
return;
1731+
APInt DemandedVecElts = DemandedElts;
1732+
bool NeedsElt = true;
1733+
// If we know the index we are inserting too, clear it from Vec check.
1734+
if (CIdx && CIdx->getValue().ult(NumElts)) {
1735+
DemandedVecElts.clearBit(CIdx->getZExtValue());
1736+
NeedsElt = DemandedElts[CIdx->getZExtValue()];
17351737
}
1738+
17361739
Known.One.setAllBits();
17371740
Known.Zero.setAllBits();
1738-
unsigned EltIdx = CIdx->getZExtValue();
1739-
// Do we demand the inserted element?
1740-
if (DemandedElts[EltIdx]) {
1741+
if (NeedsElt) {
17411742
computeKnownBits(Elt, Known, Depth + 1, Q);
17421743
// If we don't know any bits, early out.
17431744
if (Known.isUnknown())
17441745
break;
17451746
}
1746-
// We don't need the base vector element that has been inserted.
1747-
APInt DemandedVecElts = DemandedElts;
1748-
DemandedVecElts.clearBit(EltIdx);
1749-
if (!!DemandedVecElts) {
1747+
1748+
if (!DemandedVecElts.isZero()) {
17501749
computeKnownBits(Vec, DemandedVecElts, Known2, Depth + 1, Q);
17511750
Known = Known.intersectWith(Known2);
17521751
}

llvm/test/Transforms/InstCombine/insertelement.ll

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ define <4 x i32> @insert_unknown_idx(<4 x i32> %x, i32 %idx) {
1717
; CHECK-LABEL: @insert_unknown_idx(
1818
; CHECK-NEXT: [[V1:%.*]] = and <4 x i32> [[X:%.*]], <i32 7, i32 7, i32 7, i32 7>
1919
; CHECK-NEXT: [[V2:%.*]] = insertelement <4 x i32> [[V1]], i32 6, i32 [[IDX:%.*]]
20-
; CHECK-NEXT: [[V3:%.*]] = and <4 x i32> [[V2]], <i32 7, i32 7, i32 7, i32 7>
21-
; CHECK-NEXT: ret <4 x i32> [[V3]]
20+
; CHECK-NEXT: ret <4 x i32> [[V2]]
2221
;
2322
%v1 = and <4 x i32> %x, <i32 7, i32 7, i32 7, i32 7>
2423
%v2 = insertelement <4 x i32> %v1, i32 6, i32 %idx
@@ -28,11 +27,7 @@ define <4 x i32> @insert_unknown_idx(<4 x i32> %x, i32 %idx) {
2827

2928
define <2 x i8> @insert_known_any_idx(<2 x i8> %xx, i8 %yy, i32 %idx) {
3029
; CHECK-LABEL: @insert_known_any_idx(
31-
; CHECK-NEXT: [[X:%.*]] = or <2 x i8> [[XX:%.*]], <i8 16, i8 16>
32-
; CHECK-NEXT: [[Y:%.*]] = or i8 [[YY:%.*]], 16
33-
; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i8> [[X]], i8 [[Y]], i32 [[IDX:%.*]]
34-
; CHECK-NEXT: [[R:%.*]] = and <2 x i8> [[INS]], <i8 16, i8 16>
35-
; CHECK-NEXT: ret <2 x i8> [[R]]
30+
; CHECK-NEXT: ret <2 x i8> <i8 16, i8 16>
3631
;
3732
%x = or <2 x i8> %xx, <i8 16, i8 16>
3833
%y = or i8 %yy, 16

0 commit comments

Comments
 (0)