Skip to content

Commit 709abac

Browse files
committed
[SLP]Check that operand of abs does not overflow before making it part of minbitwidth transformation
Need to check that the operand of the abs intrinsic can be safely truncated before making it part of the minbitwidth transformation. Fixes #112577
1 parent 7619699 commit 709abac

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17224,9 +17224,25 @@ bool BoUpSLP::collectValuesToDemote(
1722417224
MaskedValueIsZero(I->getOperand(1), Mask, SimplifyQuery(*DL)));
1722517225
});
1722617226
};
17227+
auto AbsChecker = [&](unsigned BitWidth, unsigned OrigBitWidth) {
17228+
assert(BitWidth <= OrigBitWidth && "Unexpected bitwidths!");
17229+
return all_of(E.Scalars, [&](Value *V) {
17230+
auto *I = cast<Instruction>(V);
17231+
unsigned SignBits = OrigBitWidth - BitWidth;
17232+
APInt Mask = APInt::getBitsSetFrom(OrigBitWidth, BitWidth - 1);
17233+
unsigned Op0SignBits =
17234+
ComputeNumSignBits(I->getOperand(0), *DL, 0, AC, nullptr, DT);
17235+
return SignBits <= Op0SignBits &&
17236+
((SignBits != Op0SignBits &&
17237+
!isKnownNonNegative(I->getOperand(0), SimplifyQuery(*DL))) ||
17238+
MaskedValueIsZero(I->getOperand(0), Mask, SimplifyQuery(*DL)));
17239+
});
17240+
};
1722717241
if (ID != Intrinsic::abs) {
1722817242
Operands.push_back(getOperandEntry(&E, 1));
1722917243
CallChecker = CompChecker;
17244+
} else {
17245+
CallChecker = AbsChecker;
1723017246
}
1723117247
InstructionCost BestCost =
1723217248
std::numeric_limits<InstructionCost::CostType>::max();

llvm/test/Transforms/SLPVectorizer/abs-overflow-incorrect-minbws.ll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ define i32 @test(i32 %n) {
88
; CHECK-NEXT: [[TMP0:%.*]] = insertelement <2 x i32> poison, i32 [[N]], i32 0
99
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x i32> [[TMP0]], <2 x i32> poison, <2 x i32> zeroinitializer
1010
; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i32> [[TMP1]], <i32 1, i32 2>
11-
; CHECK-NEXT: [[TMP3:%.*]] = mul <2 x i32> [[TMP2]], <i32 273837369, i32 273837369>
12-
; CHECK-NEXT: [[TMP4:%.*]] = call <2 x i32> @llvm.abs.v2i32(<2 x i32> [[TMP3]], i1 false)
11+
; CHECK-NEXT: [[TMP3:%.*]] = zext <2 x i32> [[TMP2]] to <2 x i64>
12+
; CHECK-NEXT: [[TMP7:%.*]] = mul nuw nsw <2 x i64> [[TMP3]], <i64 273837369, i64 273837369>
13+
; CHECK-NEXT: [[TMP8:%.*]] = call <2 x i64> @llvm.abs.v2i64(<2 x i64> [[TMP7]], i1 true)
14+
; CHECK-NEXT: [[TMP4:%.*]] = trunc <2 x i64> [[TMP8]] to <2 x i32>
1315
; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i32> [[TMP4]], i32 0
1416
; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x i32> [[TMP4]], i32 1
1517
; CHECK-NEXT: [[RES1:%.*]] = add i32 [[TMP5]], [[TMP6]]

0 commit comments

Comments
 (0)