Skip to content

Commit 536cb1f

Browse files
[InstCombine] Fix for folding select-like shufflevector into floating point binary operators. (#85452)
Folding a select-like `shufflevector` into a floating point binary operators can only be done if the result is preserved for both case. In particular, if the common operand of the `shufflevector` and the floating point binary operator can be a NaN, then the transformation won't preserve the result value.
1 parent 3eb58d1 commit 536cb1f

File tree

3 files changed

+45
-9
lines changed

3 files changed

+45
-9
lines changed

llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2135,7 +2135,8 @@ static Instruction *foldSelectShuffleOfSelectShuffle(ShuffleVectorInst &Shuf) {
21352135
return new ShuffleVectorInst(X, Y, NewMask);
21362136
}
21372137

2138-
static Instruction *foldSelectShuffleWith1Binop(ShuffleVectorInst &Shuf) {
2138+
static Instruction *foldSelectShuffleWith1Binop(ShuffleVectorInst &Shuf,
2139+
const SimplifyQuery &SQ) {
21392140
assert(Shuf.isSelect() && "Must have select-equivalent shuffle");
21402141

21412142
// Are we shuffling together some value and that same value after it has been
@@ -2159,6 +2160,19 @@ static Instruction *foldSelectShuffleWith1Binop(ShuffleVectorInst &Shuf) {
21592160
if (!IdC)
21602161
return nullptr;
21612162

2163+
Value *X = Op0IsBinop ? Op1 : Op0;
2164+
2165+
// Prevent folding in the case the non-binop operand might have NaN values.
2166+
// If X can have NaN elements then we have that the floating point math
2167+
// operation in the transformed code may not preserve the exact NaN
2168+
// bit-pattern -- e.g. `fadd sNaN, 0.0 -> qNaN`.
2169+
// This makes the transformation incorrect since the original program would
2170+
// have preserved the exact NaN bit-pattern.
2171+
// Avoid the folding if X can have NaN elements.
2172+
if (Shuf.getType()->getElementType()->isFloatingPointTy() &&
2173+
!isKnownNeverNaN(X, 0, SQ))
2174+
return nullptr;
2175+
21622176
// Shuffle identity constants into the lanes that return the original value.
21632177
// Example: shuf (mul X, {-1,-2,-3,-4}), X, {0,5,6,3} --> mul X, {-1,1,1,-4}
21642178
// Example: shuf X, (add X, {-1,-2,-3,-4}), {0,1,6,7} --> add X, {0,0,-3,-4}
@@ -2175,7 +2189,6 @@ static Instruction *foldSelectShuffleWith1Binop(ShuffleVectorInst &Shuf) {
21752189

21762190
// shuf (bop X, C), X, M --> bop X, C'
21772191
// shuf X, (bop X, C), M --> bop X, C'
2178-
Value *X = Op0IsBinop ? Op1 : Op0;
21792192
Instruction *NewBO = BinaryOperator::Create(BOpcode, X, NewC);
21802193
NewBO->copyIRFlags(BO);
21812194

@@ -2241,7 +2254,8 @@ Instruction *InstCombinerImpl::foldSelectShuffle(ShuffleVectorInst &Shuf) {
22412254
if (Instruction *I = foldSelectShuffleOfSelectShuffle(Shuf))
22422255
return I;
22432256

2244-
if (Instruction *I = foldSelectShuffleWith1Binop(Shuf))
2257+
if (Instruction *I = foldSelectShuffleWith1Binop(
2258+
Shuf, getSimplifyQuery().getWithInstruction(&Shuf)))
22452259
return I;
22462260

22472261
BinaryOperator *B0, *B1;

llvm/test/Transforms/InstCombine/shuffle_select-inseltpoison.ll

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,18 @@ define <4 x i32> @srem(<4 x i32> %v) {
336336

337337
; Try FP ops/types.
338338

339-
define <4 x float> @fadd(<4 x float> %v) {
339+
define <4 x float> @fadd_maybe_nan(<4 x float> %v) {
340+
; CHECK-LABEL: @fadd_maybe_nan(
341+
; CHECK-NEXT: [[B:%.*]] = fadd <4 x float> [[V:%.*]], <float 4.100000e+01, float 4.200000e+01, float poison, float poison>
342+
; CHECK-NEXT: [[S:%.*]] = shufflevector <4 x float> [[B]], <4 x float> [[V]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>
343+
; CHECK-NEXT: ret <4 x float> [[S]]
344+
;
345+
%b = fadd <4 x float> %v, <float 41.0, float 42.0, float 43.0, float 44.0>
346+
%s = shufflevector <4 x float> %b, <4 x float> %v, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
347+
ret <4 x float> %s
348+
}
349+
350+
define <4 x float> @fadd(<4 x float> nofpclass(nan) %v) {
340351
; CHECK-LABEL: @fadd(
341352
; CHECK-NEXT: [[S:%.*]] = fadd <4 x float> [[V:%.*]], <float 4.100000e+01, float 4.200000e+01, float -0.000000e+00, float -0.000000e+00>
342353
; CHECK-NEXT: ret <4 x float> [[S]]
@@ -359,7 +370,7 @@ define <4 x double> @fsub(<4 x double> %v) {
359370

360371
; Propagate any FMF.
361372

362-
define <4 x float> @fmul(<4 x float> %v) {
373+
define <4 x float> @fmul(<4 x float> nofpclass(nan) %v) {
363374
; CHECK-LABEL: @fmul(
364375
; CHECK-NEXT: [[S:%.*]] = fmul nnan ninf <4 x float> [[V:%.*]], <float 4.100000e+01, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>
365376
; CHECK-NEXT: ret <4 x float> [[S]]
@@ -380,7 +391,7 @@ define <4 x double> @fdiv_constant_op0(<4 x double> %v) {
380391
ret <4 x double> %s
381392
}
382393

383-
define <4 x double> @fdiv_constant_op1(<4 x double> %v) {
394+
define <4 x double> @fdiv_constant_op1(<4 x double> nofpclass(nan) %v) {
384395
; CHECK-LABEL: @fdiv_constant_op1(
385396
; CHECK-NEXT: [[S:%.*]] = fdiv reassoc <4 x double> [[V:%.*]], <double undef, double 1.000000e+00, double 4.300000e+01, double 4.400000e+01>
386397
; CHECK-NEXT: ret <4 x double> [[S]]

llvm/test/Transforms/InstCombine/shuffle_select.ll

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,18 @@ define <4 x i32> @srem(<4 x i32> %v) {
336336

337337
; Try FP ops/types.
338338

339-
define <4 x float> @fadd(<4 x float> %v) {
339+
define <4 x float> @fadd_maybe_nan(<4 x float> %v) {
340+
; CHECK-LABEL: @fadd_maybe_nan(
341+
; CHECK-NEXT: [[B:%.*]] = fadd <4 x float> [[V:%.*]], <float 4.100000e+01, float 4.200000e+01, float poison, float poison>
342+
; CHECK-NEXT: [[S:%.*]] = shufflevector <4 x float> [[B]], <4 x float> [[V]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>
343+
; CHECK-NEXT: ret <4 x float> [[S]]
344+
;
345+
%b = fadd <4 x float> %v, <float 41.0, float 42.0, float 43.0, float 44.0>
346+
%s = shufflevector <4 x float> %b, <4 x float> %v, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
347+
ret <4 x float> %s
348+
}
349+
350+
define <4 x float> @fadd(<4 x float> nofpclass(nan) %v) {
340351
; CHECK-LABEL: @fadd(
341352
; CHECK-NEXT: [[S:%.*]] = fadd <4 x float> [[V:%.*]], <float 4.100000e+01, float 4.200000e+01, float -0.000000e+00, float -0.000000e+00>
342353
; CHECK-NEXT: ret <4 x float> [[S]]
@@ -359,7 +370,7 @@ define <4 x double> @fsub(<4 x double> %v) {
359370

360371
; Propagate any FMF.
361372

362-
define <4 x float> @fmul(<4 x float> %v) {
373+
define <4 x float> @fmul(<4 x float> nofpclass(nan) %v) {
363374
; CHECK-LABEL: @fmul(
364375
; CHECK-NEXT: [[S:%.*]] = fmul nnan ninf <4 x float> [[V:%.*]], <float 4.100000e+01, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>
365376
; CHECK-NEXT: ret <4 x float> [[S]]
@@ -380,7 +391,7 @@ define <4 x double> @fdiv_constant_op0(<4 x double> %v) {
380391
ret <4 x double> %s
381392
}
382393

383-
define <4 x double> @fdiv_constant_op1(<4 x double> %v) {
394+
define <4 x double> @fdiv_constant_op1(<4 x double> nofpclass(nan) %v) {
384395
; CHECK-LABEL: @fdiv_constant_op1(
385396
; CHECK-NEXT: [[S:%.*]] = fdiv reassoc <4 x double> [[V:%.*]], <double undef, double 1.000000e+00, double 4.300000e+01, double 4.400000e+01>
386397
; CHECK-NEXT: ret <4 x double> [[S]]

0 commit comments

Comments
 (0)