Skip to content

Commit e9fd428

Browse files
alexey-bataevakadutta
authored andcommitted
[SLP]Do not allow undefs being combined with divs
Undefs/poisons with divs in vector operations lead to undefined behavior, disabling this combination Fixes llvm#162663
1 parent 119743d commit e9fd428

File tree

2 files changed

+106
-3
lines changed

2 files changed

+106
-3
lines changed

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10664,18 +10664,23 @@ class InstructionsCompatibilityAnalysis {
1066410664
void findAndSetMainInstruction(ArrayRef<Value *> VL, const BoUpSLP &R) {
1066510665
BasicBlock *Parent = nullptr;
1066610666
// Checks if the instruction has supported opcode.
10667-
auto IsSupportedInstruction = [&](Instruction *I) {
10667+
auto IsSupportedInstruction = [&](Instruction *I, bool AnyUndef) {
10668+
if (AnyUndef && (I->isIntDivRem() || I->isFPDivRem() || isa<CallInst>(I)))
10669+
return false;
1066810670
return I && isSupportedOpcode(I->getOpcode()) &&
1066910671
(!doesNotNeedToBeScheduled(I) || !R.isVectorized(I));
1067010672
};
1067110673
// Exclude operands instructions immediately to improve compile time, it
1067210674
// will be unable to schedule anyway.
1067310675
SmallDenseSet<Value *, 8> Operands;
1067410676
SmallMapVector<unsigned, SmallVector<Instruction *>, 4> Candidates;
10677+
bool AnyUndef = false;
1067510678
for (Value *V : VL) {
1067610679
auto *I = dyn_cast<Instruction>(V);
10677-
if (!I)
10680+
if (!I) {
10681+
AnyUndef |= isa<UndefValue>(V);
1067810682
continue;
10683+
}
1067910684
if (!DT.isReachableFromEntry(I->getParent()))
1068010685
continue;
1068110686
if (Candidates.empty()) {
@@ -10710,7 +10715,7 @@ class InstructionsCompatibilityAnalysis {
1071010715
if (P.second.size() < BestOpcodeNum)
1071110716
continue;
1071210717
for (Instruction *I : P.second) {
10713-
if (IsSupportedInstruction(I) && !Operands.contains(I)) {
10718+
if (IsSupportedInstruction(I, AnyUndef) && !Operands.contains(I)) {
1071410719
MainOp = I;
1071510720
BestOpcodeNum = P.second.size();
1071610721
break;
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
2+
; RUN: opt --passes=slp-vectorizer -S -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
3+
4+
define i32 @test(i1 %tobool2.not, i64 %conv21) {
5+
; CHECK-LABEL: define i32 @test(
6+
; CHECK-SAME: i1 [[TOBOOL2_NOT:%.*]], i64 [[CONV21:%.*]]) {
7+
; CHECK-NEXT: [[ENTRY:.*]]:
8+
; CHECK-NEXT: br label %[[WHILE_BODY:.*]]
9+
; CHECK: [[WHILE_BODY]]:
10+
; CHECK-NEXT: [[Q24_659:%.*]] = phi i32 [ [[Q24_655:%.*]], %[[IF_END35:.*]] ], [ 0, %[[ENTRY]] ]
11+
; CHECK-NEXT: [[L15_1:%.*]] = phi i32 [ [[L15_4:%.*]], %[[IF_END35]] ], [ 0, %[[ENTRY]] ]
12+
; CHECK-NEXT: br i1 [[TOBOOL2_NOT]], label %[[IF_END4:.*]], label %[[Q:.*]]
13+
; CHECK: [[IF_END4]]:
14+
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[Q24_659]], 0
15+
; CHECK-NEXT: br label %[[AB:.*]]
16+
; CHECK: [[AB]]:
17+
; CHECK-NEXT: [[Q24_658:%.*]] = phi i32 [ [[Q24_660:%.*]], %[[IF_END35]] ], [ 0, %[[IF_END4]] ]
18+
; CHECK-NEXT: [[M_1:%.*]] = phi i1 [ false, %[[IF_END35]] ], [ [[TMP0]], %[[IF_END4]] ]
19+
; CHECK-NEXT: [[O_2:%.*]] = phi i32 [ [[O_7:%.*]], %[[IF_END35]] ], [ 0, %[[IF_END4]] ]
20+
; CHECK-NEXT: [[Q24_2:%.*]] = phi i32 [ [[Q24_7:%.*]], %[[IF_END35]] ], [ 0, %[[IF_END4]] ]
21+
; CHECK-NEXT: br i1 [[M_1]], label %[[AE:.*]], label %[[AC:.*]]
22+
; CHECK: [[Q]]:
23+
; CHECK-NEXT: [[TOBOOL16_NOT:%.*]] = icmp ne i32 [[L15_1]], 0
24+
; CHECK-NEXT: [[SPEC_SELECT2:%.*]] = zext i1 [[TOBOOL16_NOT]] to i32
25+
; CHECK-NEXT: br label %[[AE]]
26+
; CHECK: [[AE]]:
27+
; CHECK-NEXT: [[Q24_655]] = phi i32 [ [[Q24_658]], %[[AB]] ], [ 0, %[[Q]] ]
28+
; CHECK-NEXT: [[M_3:%.*]] = phi i64 [ 0, %[[AB]] ], [ 1, %[[Q]] ]
29+
; CHECK-NEXT: [[L15_4]] = phi i32 [ poison, %[[AB]] ], [ [[SPEC_SELECT2]], %[[Q]] ]
30+
; CHECK-NEXT: [[O_4:%.*]] = phi i32 [ [[O_2]], %[[AB]] ], [ 0, %[[Q]] ]
31+
; CHECK-NEXT: [[Q24_4:%.*]] = phi i32 [ [[Q24_2]], %[[AB]] ], [ 0, %[[Q]] ]
32+
; CHECK-NEXT: br i1 [[TOBOOL2_NOT]], label %[[IF_END35]], label %[[IF_THEN20:.*]]
33+
; CHECK: [[IF_THEN20]]:
34+
; CHECK-NEXT: [[DIV22:%.*]] = udiv i64 [[M_3]], [[CONV21]]
35+
; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[DIV22]] to i32
36+
; CHECK-NEXT: [[CONV23:%.*]] = sub i32 0, [[TMP1]]
37+
; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[M_3]] to i32
38+
; CHECK-NEXT: [[CONV25:%.*]] = xor i32 [[TMP2]], 1
39+
; CHECK-NEXT: br label %[[IF_END35]]
40+
; CHECK: [[AC]]:
41+
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL2_NOT]], i32 [[Q24_2]], i32 [[O_2]]
42+
; CHECK-NEXT: ret i32 [[SPEC_SELECT]]
43+
; CHECK: [[IF_END35]]:
44+
; CHECK-NEXT: [[Q24_660]] = phi i32 [ 0, %[[AE]] ], [ [[CONV25]], %[[IF_THEN20]] ]
45+
; CHECK-NEXT: [[O_7]] = phi i32 [ [[O_4]], %[[AE]] ], [ [[CONV23]], %[[IF_THEN20]] ]
46+
; CHECK-NEXT: [[Q24_7]] = phi i32 [ [[Q24_4]], %[[AE]] ], [ [[CONV25]], %[[IF_THEN20]] ]
47+
; CHECK-NEXT: br i1 [[TOBOOL2_NOT]], label %[[WHILE_BODY]], label %[[AB]]
48+
;
49+
entry:
50+
br label %while.body
51+
52+
while.body:
53+
%q24.659 = phi i32 [ %q24.655, %if.end35 ], [ 0, %entry ]
54+
%l15.1 = phi i32 [ %l15.4, %if.end35 ], [ 0, %entry ]
55+
br i1 %tobool2.not, label %if.end4, label %q
56+
57+
if.end4:
58+
%0 = icmp eq i32 %q24.659, 0
59+
br label %ab
60+
61+
ab:
62+
%q24.658 = phi i32 [ %q24.660, %if.end35 ], [ 0, %if.end4 ]
63+
%m.1 = phi i1 [ false, %if.end35 ], [ %0, %if.end4 ]
64+
%o.2 = phi i32 [ %o.7, %if.end35 ], [ 0, %if.end4 ]
65+
%q24.2 = phi i32 [ %q24.7, %if.end35 ], [ 0, %if.end4 ]
66+
br i1 %m.1, label %ae, label %ac
67+
68+
q:
69+
%tobool16.not = icmp ne i32 %l15.1, 0
70+
%spec.select2 = zext i1 %tobool16.not to i32
71+
br label %ae
72+
73+
ae:
74+
%q24.655 = phi i32 [ %q24.658, %ab ], [ 0, %q ]
75+
%m.3 = phi i64 [ 0, %ab ], [ 1, %q ]
76+
%l15.4 = phi i32 [ poison, %ab ], [ %spec.select2, %q ]
77+
%o.4 = phi i32 [ %o.2, %ab ], [ 0, %q ]
78+
%q24.4 = phi i32 [ %q24.2, %ab ], [ 0, %q ]
79+
br i1 %tobool2.not, label %if.end35, label %if.then20
80+
81+
if.then20:
82+
%div22 = udiv i64 %m.3, %conv21
83+
%1 = trunc i64 %div22 to i32
84+
%conv23 = sub i32 0, %1
85+
%2 = trunc i64 %m.3 to i32
86+
%conv25 = xor i32 %2, 1
87+
br label %if.end35
88+
89+
ac:
90+
%spec.select = select i1 %tobool2.not, i32 %q24.2, i32 %o.2
91+
ret i32 %spec.select
92+
93+
if.end35:
94+
%q24.660 = phi i32 [ 0, %ae ], [ %conv25, %if.then20 ]
95+
%o.7 = phi i32 [ %o.4, %ae ], [ %conv23, %if.then20 ]
96+
%q24.7 = phi i32 [ %q24.4, %ae ], [ %conv25, %if.then20 ]
97+
br i1 %tobool2.not, label %while.body, label %ab
98+
}

0 commit comments

Comments
 (0)