Skip to content

Commit 4ca25c6

Browse files
committed
[Reassociate] prevent partial undef negation replacement
As shown in the examples in issue llvm#57683, we allow matching vectors with poison (undef) in this transform (and possibly more), but we can't then use the partially defined value as a replacement value in other expressions blindly. This seems to be avoided in simpler examples of reassociation, and other passes should be able to clean up the redundant op seen in these tests.
1 parent eb2ac0a commit 4ca25c6

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

llvm/lib/Transforms/Scalar/Reassociate.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,12 @@ static Value *NegateValue(Value *V, Instruction *BI,
887887
// be zapped by reassociate later, so we don't need much finesse here.
888888
Instruction *TheNeg = dyn_cast<Instruction>(U);
889889

890+
// We can't safely propagate a vector zero constant with poison/undef lanes.
891+
Constant *C;
892+
if (match(TheNeg, m_BinOp(m_Constant(C), m_Value())) &&
893+
C->containsUndefOrPoisonElement())
894+
continue;
895+
890896
// Verify that the negate is in this function, V might be a constant expr.
891897
if (!TheNeg ||
892898
TheNeg->getParent()->getParent() != BI->getParent()->getParent())

llvm/test/Transforms/Reassociate/negation.ll

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,14 @@ define <2 x i32> @negate_vec_undefs(<2 x i32> %a, <2 x i32> %b, <2 x i32> %z) {
4444
ret <2 x i32> %f
4545
}
4646

47-
; FIXME: Replacing x with a partial undef negation is a miscompile.
47+
; Replacing %x with a partial undef negation is a miscompile.
4848

4949
define <2 x i32> @PR57683(<2 x i32> %x) {
5050
; CHECK-LABEL: @PR57683(
5151
; CHECK-NEXT: [[PARTIAL_NEG:%.*]] = sub <2 x i32> <i32 poison, i32 0>, [[X:%.*]]
5252
; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <2 x i32> [[PARTIAL_NEG]], <2 x i32> [[X]], <2 x i32> <i32 1, i32 3>
53-
; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[PARTIAL_NEG]], <i32 1, i32 1>
53+
; CHECK-NEXT: [[X_NEG:%.*]] = sub <2 x i32> zeroinitializer, [[X]]
54+
; CHECK-NEXT: [[SUB:%.*]] = add <2 x i32> [[X_NEG]], <i32 1, i32 1>
5455
; CHECK-NEXT: [[R:%.*]] = add <2 x i32> [[SUB]], [[SHUF]]
5556
; CHECK-NEXT: ret <2 x i32> [[R]]
5657
;
@@ -65,7 +66,8 @@ define <2 x float> @PR57683_FP(<2 x float> %x) {
6566
; CHECK-LABEL: @PR57683_FP(
6667
; CHECK-NEXT: [[PARTIAL_NEG:%.*]] = fsub reassoc nsz <2 x float> <float poison, float 0.000000e+00>, [[X:%.*]]
6768
; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <2 x float> [[PARTIAL_NEG]], <2 x float> [[X]], <2 x i32> <i32 1, i32 3>
68-
; CHECK-NEXT: [[SUB:%.*]] = fadd reassoc nsz <2 x float> [[PARTIAL_NEG]], <float 1.000000e+00, float 1.000000e+00>
69+
; CHECK-NEXT: [[X_NEG:%.*]] = fneg reassoc nsz <2 x float> [[X]]
70+
; CHECK-NEXT: [[SUB:%.*]] = fadd reassoc nsz <2 x float> [[X_NEG]], <float 1.000000e+00, float 1.000000e+00>
6971
; CHECK-NEXT: [[R:%.*]] = fadd reassoc nsz <2 x float> [[SUB]], [[SHUF]]
7072
; CHECK-NEXT: ret <2 x float> [[R]]
7173
;

0 commit comments

Comments
 (0)