Skip to content

Commit fde8eb0

Browse files
committed
[InstCombine] visitMaskedMerge(): when unfolding, sanitize undef constants (PR45955)
We can't leave undef vector element constants as-is, it is a miscompile, so we need to sanitize them. We have two vectors (C and ~C): * We can't replace undef with 0 in both of them * We can't replace undef with 0 in only one of them * We could replace undef with -1 in both of them * We could replace undef with -1 in only one(!) of them * We could replace undef with -1 in one and 0 in another one of them. Therefore, it seems best to go with the last option, since otherwise we'd loose knowledge that C and ~C have no common bits set, which seems more important than preserving partial undef knowledge. Fixes https://bugs.llvm.org/show_bug.cgi?id=45955
1 parent a055e38 commit fde8eb0

File tree

2 files changed

+8
-5
lines changed

2 files changed

+8
-5
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3049,6 +3049,9 @@ static Instruction *visitMaskedMerge(BinaryOperator &I,
30493049

30503050
Constant *C;
30513051
if (D->hasOneUse() && match(M, m_Constant(C))) {
3052+
// Propagating undef is unsafe. Clamp undef elements to -1.
3053+
Type *EltTy = C->getType()->getScalarType();
3054+
C = Constant::replaceUndefsWith(C, ConstantInt::getAllOnesValue(EltTy));
30523055
// Unfold.
30533056
Value *LHS = Builder.CreateAnd(X, C);
30543057
Value *NotC = Builder.CreateNot(C);

llvm/test/Transforms/InstCombine/unfold-masked-merge-with-const-mask-vector.ll

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ define <2 x i4> @splat (<2 x i4> %x, <2 x i4> %y) {
2121

2222
define <3 x i4> @splat_undef (<3 x i4> %x, <3 x i4> %y) {
2323
; CHECK-LABEL: @splat_undef(
24-
; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i4> [[X:%.*]], <i4 -2, i4 undef, i4 -2>
25-
; CHECK-NEXT: [[TMP2:%.*]] = and <3 x i4> [[Y:%.*]], <i4 1, i4 undef, i4 1>
24+
; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i4> [[X:%.*]], <i4 -2, i4 -1, i4 -2>
25+
; CHECK-NEXT: [[TMP2:%.*]] = and <3 x i4> [[Y:%.*]], <i4 1, i4 0, i4 1>
2626
; CHECK-NEXT: [[R:%.*]] = or <3 x i4> [[TMP1]], [[TMP2]]
2727
; CHECK-NEXT: ret <3 x i4> [[R]]
2828
;
@@ -85,8 +85,8 @@ define <2 x i4> @in_constant_varx_14_nonsplat(<2 x i4> %x, <2 x i4> %mask) {
8585

8686
define <3 x i4> @in_constant_varx_14_undef(<3 x i4> %x, <3 x i4> %mask) {
8787
; CHECK-LABEL: @in_constant_varx_14_undef(
88-
; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i4> [[X:%.*]], <i4 1, i4 undef, i4 1>
89-
; CHECK-NEXT: [[R:%.*]] = or <3 x i4> [[TMP1]], <i4 -2, i4 undef, i4 6>
88+
; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i4> [[X:%.*]], <i4 1, i4 -1, i4 1>
89+
; CHECK-NEXT: [[R:%.*]] = or <3 x i4> [[TMP1]], <i4 -2, i4 0, i4 6>
9090
; CHECK-NEXT: ret <3 x i4> [[R]]
9191
;
9292
%n0 = xor <3 x i4> %x, <i4 14, i4 undef, i4 7> ; %x
@@ -133,7 +133,7 @@ define <2 x i4> @in_constant_14_vary_nonsplat(<2 x i4> %y, <2 x i4> %mask) {
133133

134134
define <3 x i4> @in_constant_14_vary_undef(<3 x i4> %y, <3 x i4> %mask) {
135135
; CHECK-LABEL: @in_constant_14_vary_undef(
136-
; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i4> [[Y:%.*]], <i4 -2, i4 undef, i4 -2>
136+
; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i4> [[Y:%.*]], <i4 -2, i4 0, i4 -2>
137137
; CHECK-NEXT: [[R:%.*]] = or <3 x i4> [[TMP1]], <i4 0, i4 undef, i4 1>
138138
; CHECK-NEXT: ret <3 x i4> [[R]]
139139
;

0 commit comments

Comments
 (0)