Skip to content

Commit 9f72c98

Browse files
alexey-bataevtru
authored andcommitted
[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 (cherry picked from commit 709abac)
1 parent edded5a commit 9f72c98

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
@@ -15440,9 +15440,25 @@ bool BoUpSLP::collectValuesToDemote(
1544015440
MaskedValueIsZero(I->getOperand(1), Mask, SimplifyQuery(*DL)));
1544115441
});
1544215442
};
15443+
auto AbsChecker = [&](unsigned BitWidth, unsigned OrigBitWidth) {
15444+
assert(BitWidth <= OrigBitWidth && "Unexpected bitwidths!");
15445+
return all_of(E.Scalars, [&](Value *V) {
15446+
auto *I = cast<Instruction>(V);
15447+
unsigned SignBits = OrigBitWidth - BitWidth;
15448+
APInt Mask = APInt::getBitsSetFrom(OrigBitWidth, BitWidth - 1);
15449+
unsigned Op0SignBits =
15450+
ComputeNumSignBits(I->getOperand(0), *DL, 0, AC, nullptr, DT);
15451+
return SignBits <= Op0SignBits &&
15452+
((SignBits != Op0SignBits &&
15453+
!isKnownNonNegative(I->getOperand(0), SimplifyQuery(*DL))) ||
15454+
MaskedValueIsZero(I->getOperand(0), Mask, SimplifyQuery(*DL)));
15455+
});
15456+
};
1544315457
if (ID != Intrinsic::abs) {
1544415458
Operands.push_back(getOperandEntry(&E, 1));
1544515459
CallChecker = CompChecker;
15460+
} else {
15461+
CallChecker = AbsChecker;
1544615462
}
1544715463
InstructionCost BestCost =
1544815464
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)