Skip to content

Commit c4bfd01

Browse files
alexey-bataevllvmbot
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 e2f6ef4 commit c4bfd01

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)