Skip to content

Commit 22897bc

Browse files
committed
[SDAG] Fix incorrect use of undef for boolean contents (PR63055)
FoldSetCC() returns UNDEF in a number of cases. However, the SetCC result must follow BooleanContents. Unless the type is a pre-legalization i1 or we have UndefinedBooleanContents, the use of UNDEF will not uphold the requirement that the top bits are either zero or match the low bit. In such cases, return zero instead. Fixes llvm#63055. Differential Revision: https://reviews.llvm.org/D151883 (cherry picked from commit e506bfa)
1 parent 72ef6d7 commit 22897bc

File tree

3 files changed

+24
-14
lines changed

3 files changed

+24
-14
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

+19-9
Original file line numberDiff line numberDiff line change
@@ -2381,6 +2381,16 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
23812381
ISD::CondCode Cond, const SDLoc &dl) {
23822382
EVT OpVT = N1.getValueType();
23832383

2384+
auto GetUndefBooleanConstant = [&]() {
2385+
if (VT.getScalarType() == MVT::i1 ||
2386+
TLI->getBooleanContents(OpVT) ==
2387+
TargetLowering::UndefinedBooleanContent)
2388+
return getUNDEF(VT);
2389+
// ZeroOrOne / ZeroOrNegative require specific values for the high bits,
2390+
// so we cannot use getUNDEF(). Return zero instead.
2391+
return getConstant(0, dl, VT);
2392+
};
2393+
23842394
// These setcc operations always fold.
23852395
switch (Cond) {
23862396
default: break;
@@ -2410,12 +2420,12 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
24102420
// icmp eq/ne X, undef -> undef.
24112421
if ((N1.isUndef() || N2.isUndef()) &&
24122422
(Cond == ISD::SETEQ || Cond == ISD::SETNE))
2413-
return getUNDEF(VT);
2423+
return GetUndefBooleanConstant();
24142424

24152425
// If both operands are undef, we can return undef for int comparison.
24162426
// icmp undef, undef -> undef.
24172427
if (N1.isUndef() && N2.isUndef())
2418-
return getUNDEF(VT);
2428+
return GetUndefBooleanConstant();
24192429

24202430
// icmp X, X -> true/false
24212431
// icmp X, undef -> true/false because undef could be X.
@@ -2441,34 +2451,34 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
24412451
switch (Cond) {
24422452
default: break;
24432453
case ISD::SETEQ: if (R==APFloat::cmpUnordered)
2444-
return getUNDEF(VT);
2454+
return GetUndefBooleanConstant();
24452455
[[fallthrough]];
24462456
case ISD::SETOEQ: return getBoolConstant(R==APFloat::cmpEqual, dl, VT,
24472457
OpVT);
24482458
case ISD::SETNE: if (R==APFloat::cmpUnordered)
2449-
return getUNDEF(VT);
2459+
return GetUndefBooleanConstant();
24502460
[[fallthrough]];
24512461
case ISD::SETONE: return getBoolConstant(R==APFloat::cmpGreaterThan ||
24522462
R==APFloat::cmpLessThan, dl, VT,
24532463
OpVT);
24542464
case ISD::SETLT: if (R==APFloat::cmpUnordered)
2455-
return getUNDEF(VT);
2465+
return GetUndefBooleanConstant();
24562466
[[fallthrough]];
24572467
case ISD::SETOLT: return getBoolConstant(R==APFloat::cmpLessThan, dl, VT,
24582468
OpVT);
24592469
case ISD::SETGT: if (R==APFloat::cmpUnordered)
2460-
return getUNDEF(VT);
2470+
return GetUndefBooleanConstant();
24612471
[[fallthrough]];
24622472
case ISD::SETOGT: return getBoolConstant(R==APFloat::cmpGreaterThan, dl,
24632473
VT, OpVT);
24642474
case ISD::SETLE: if (R==APFloat::cmpUnordered)
2465-
return getUNDEF(VT);
2475+
return GetUndefBooleanConstant();
24662476
[[fallthrough]];
24672477
case ISD::SETOLE: return getBoolConstant(R==APFloat::cmpLessThan ||
24682478
R==APFloat::cmpEqual, dl, VT,
24692479
OpVT);
24702480
case ISD::SETGE: if (R==APFloat::cmpUnordered)
2471-
return getUNDEF(VT);
2481+
return GetUndefBooleanConstant();
24722482
[[fallthrough]];
24732483
case ISD::SETOGE: return getBoolConstant(R==APFloat::cmpGreaterThan ||
24742484
R==APFloat::cmpEqual, dl, VT, OpVT);
@@ -2513,7 +2523,7 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
25132523
case 1: // Known true.
25142524
return getBoolConstant(true, dl, VT, OpVT);
25152525
case 2: // Undefined.
2516-
return getUNDEF(VT);
2526+
return GetUndefBooleanConstant();
25172527
}
25182528
}
25192529

llvm/test/CodeGen/X86/avx512-insert-extract.ll

+3-2
Original file line numberDiff line numberDiff line change
@@ -1920,10 +1920,11 @@ define i96 @test_insertelement_variable_v96i1(<96 x i8> %a, i8 %b, i32 %index) {
19201920
; KNL-NEXT: vpinsrb $14, 720(%rbp), %xmm3, %xmm3
19211921
; KNL-NEXT: vpinsrb $15, 728(%rbp), %xmm3, %xmm3
19221922
; KNL-NEXT: vinserti128 $1, %xmm3, %ymm2, %ymm2
1923-
; KNL-NEXT: vpcmpeqb %ymm0, %ymm2, %ymm0
1924-
; KNL-NEXT: vpternlogq $15, %zmm0, %zmm0, %zmm0
1923+
; KNL-NEXT: vpcmpeqb %ymm0, %ymm2, %ymm2
1924+
; KNL-NEXT: vpternlogq $15, %zmm2, %zmm2, %zmm2
19251925
; KNL-NEXT: cmpb $0, 736(%rbp)
19261926
; KNL-NEXT: vmovdqa %ymm0, {{[0-9]+}}(%rsp)
1927+
; KNL-NEXT: vmovdqa %ymm2, {{[0-9]+}}(%rsp)
19271928
; KNL-NEXT: vmovdqa64 %zmm1, (%rsp)
19281929
; KNL-NEXT: setne (%rsp,%rax)
19291930
; KNL-NEXT: vpmovsxbd (%rsp), %zmm0

llvm/test/CodeGen/X86/setcc.ll

+2-3
Original file line numberDiff line numberDiff line change
@@ -339,17 +339,16 @@ define i32 @PR55138(i32 %x) {
339339
ret i32 %and
340340
}
341341

342-
; FIXME: Miscompile.
343342
define i64 @pr63055(double %arg) {
344343
; X86-LABEL: pr63055:
345344
; X86: ## %bb.0:
346-
; X86-NEXT: movl $255, %eax
345+
; X86-NEXT: movl $1, %eax
347346
; X86-NEXT: xorl %edx, %edx
348347
; X86-NEXT: retl
349348
;
350349
; X64-LABEL: pr63055:
351350
; X64: ## %bb.0:
352-
; X64-NEXT: movl $255, %eax
351+
; X64-NEXT: movl $1, %eax
353352
; X64-NEXT: retq
354353
%fcmp = fcmp une double 0x7FF8000000000000, %arg
355354
%ext = zext i1 %fcmp to i64

0 commit comments

Comments
 (0)