llvm.org GIT mirror llvm / e8b81e0
[InstCombine] Avoid incorrect folding of select into phi nodes when incoming element is a vector type Summary: We are incorrectly folding selects into phi nodes when the incoming value of a phi node is a constant vector. This optimization is done in `FoldOpIntoPhi` when the select condition is a phi node with constant incoming values. Without the fix, we are miscompiling (i.e. incorrectly folding the select into the phi node) when the vector contains non-zero elements. This patch fixes the miscompile and we will correctly fold based on the select vector operand (see added test cases). Reviewers: majnemer, sanjoy, spatel Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D31189 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298845 91177308-0d34-0410-b5e6-96231b3b80d8 Anna Thomas 3 years ago
2 changed file(s) with 43 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
907907 // Beware of ConstantExpr: it may eventually evaluate to getNullValue,
908908 // even if currently isNullValue gives false.
909909 Constant *InC = dyn_cast(PN->getIncomingValue(i));
910 if (InC && !isa(InC))
910 // For vector constants, we cannot use isNullValue to fold into
911 // FalseVInPred versus TrueVInPred. When we have individual nonzero
912 // elements in the vector, we will incorrectly fold InC to
913 // `TrueVInPred`.
914 if (InC && !isa(InC) && !isa(InC->getType()))
911915 InV = InC->isNullValue() ? FalseVInPred : TrueVInPred;
912916 else
913917 InV = Builder->CreateSelect(PN->getIncomingValue(i),
88 delay:
99 br label %final
1010
11 ; CHECK-LABEL: @foo
1112 ; CHECK-LABEL: final:
1213 ; CHECK: phi i32 [ 1, %entry ], [ select (i1 icmp eq (i32* @A, i32* @B), i32 2, i32 1), %delay ]
1314 final:
1617 ret i32 %value
1718 }
1819
20
21 ; test folding of select into phi for vectors.
22 define <4 x i64> @vec1(i1 %which) {
23 entry:
24 br i1 %which, label %final, label %delay
25
26 delay:
27 br label %final
28
29 final:
30 ; CHECK-LABEL: @vec1
31 ; CHECK-LABEL: final:
32 ; CHECK: %phinode = phi <4 x i64> [ zeroinitializer, %entry ], [ , %delay ]
33 ; CHECK-NOT: select
34 ; CHECK: ret <4 x i64> %phinode
35 %phinode = phi <4 x i1> [ , %entry ], [ , %delay ]
36 %sel = select <4 x i1> %phinode, <4 x i64> zeroinitializer, <4 x i64>
37 ret <4 x i64> %sel
38 }
39
40 define <4 x i64> @vec2(i1 %which) {
41 entry:
42 br i1 %which, label %final, label %delay
43
44 delay:
45 br label %final
46
47 final:
48 ; CHECK-LABEL: @vec2
49 ; CHECK-LABEL: final:
50 ; CHECK: %phinode = phi <4 x i64> [ , %entry ], [ , %delay ]
51 ; CHECK-NOT: select
52 ; CHECK: ret <4 x i64> %phinode
53 %phinode = phi <4 x i1> [ , %entry ], [ , %delay ]
54 %sel = select <4 x i1> %phinode, <4 x i64> zeroinitializer, <4 x i64>
55 ret <4 x i64> %sel
56 }