Skip to content

Commit e506bfa

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
1 parent 3ddd186 commit e506bfa

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
@@ -2436,6 +2436,16 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
24362436
ISD::CondCode Cond, const SDLoc &dl) {
24372437
EVT OpVT = N1.getValueType();
24382438

2439+
auto GetUndefBooleanConstant = [&]() {
2440+
if (VT.getScalarType() == MVT::i1 ||
2441+
TLI->getBooleanContents(OpVT) ==
2442+
TargetLowering::UndefinedBooleanContent)
2443+
return getUNDEF(VT);
2444+
// ZeroOrOne / ZeroOrNegative require specific values for the high bits,
2445+
// so we cannot use getUNDEF(). Return zero instead.
2446+
return getConstant(0, dl, VT);
2447+
};
2448+
24392449
// These setcc operations always fold.
24402450
switch (Cond) {
24412451
default: break;
@@ -2465,12 +2475,12 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
24652475
// icmp eq/ne X, undef -> undef.
24662476
if ((N1.isUndef() || N2.isUndef()) &&
24672477
(Cond == ISD::SETEQ || Cond == ISD::SETNE))
2468-
return getUNDEF(VT);
2478+
return GetUndefBooleanConstant();
24692479

24702480
// If both operands are undef, we can return undef for int comparison.
24712481
// icmp undef, undef -> undef.
24722482
if (N1.isUndef() && N2.isUndef())
2473-
return getUNDEF(VT);
2483+
return GetUndefBooleanConstant();
24742484

24752485
// icmp X, X -> true/false
24762486
// icmp X, undef -> true/false because undef could be X.
@@ -2496,34 +2506,34 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
24962506
switch (Cond) {
24972507
default: break;
24982508
case ISD::SETEQ: if (R==APFloat::cmpUnordered)
2499-
return getUNDEF(VT);
2509+
return GetUndefBooleanConstant();
25002510
[[fallthrough]];
25012511
case ISD::SETOEQ: return getBoolConstant(R==APFloat::cmpEqual, dl, VT,
25022512
OpVT);
25032513
case ISD::SETNE: if (R==APFloat::cmpUnordered)
2504-
return getUNDEF(VT);
2514+
return GetUndefBooleanConstant();
25052515
[[fallthrough]];
25062516
case ISD::SETONE: return getBoolConstant(R==APFloat::cmpGreaterThan ||
25072517
R==APFloat::cmpLessThan, dl, VT,
25082518
OpVT);
25092519
case ISD::SETLT: if (R==APFloat::cmpUnordered)
2510-
return getUNDEF(VT);
2520+
return GetUndefBooleanConstant();
25112521
[[fallthrough]];
25122522
case ISD::SETOLT: return getBoolConstant(R==APFloat::cmpLessThan, dl, VT,
25132523
OpVT);
25142524
case ISD::SETGT: if (R==APFloat::cmpUnordered)
2515-
return getUNDEF(VT);
2525+
return GetUndefBooleanConstant();
25162526
[[fallthrough]];
25172527
case ISD::SETOGT: return getBoolConstant(R==APFloat::cmpGreaterThan, dl,
25182528
VT, OpVT);
25192529
case ISD::SETLE: if (R==APFloat::cmpUnordered)
2520-
return getUNDEF(VT);
2530+
return GetUndefBooleanConstant();
25212531
[[fallthrough]];
25222532
case ISD::SETOLE: return getBoolConstant(R==APFloat::cmpLessThan ||
25232533
R==APFloat::cmpEqual, dl, VT,
25242534
OpVT);
25252535
case ISD::SETGE: if (R==APFloat::cmpUnordered)
2526-
return getUNDEF(VT);
2536+
return GetUndefBooleanConstant();
25272537
[[fallthrough]];
25282538
case ISD::SETOGE: return getBoolConstant(R==APFloat::cmpGreaterThan ||
25292539
R==APFloat::cmpEqual, dl, VT, OpVT);
@@ -2568,7 +2578,7 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
25682578
case 1: // Known true.
25692579
return getBoolConstant(true, dl, VT, OpVT);
25702580
case 2: // Undefined.
2571-
return getUNDEF(VT);
2581+
return GetUndefBooleanConstant();
25722582
}
25732583
}
25742584

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -1878,10 +1878,11 @@ define i96 @test_insertelement_variable_v96i1(<96 x i8> %a, i8 %b, i32 %index) n
18781878
; KNL-NEXT: vpinsrb $14, 720(%rbp), %xmm3, %xmm3
18791879
; KNL-NEXT: vpinsrb $15, 728(%rbp), %xmm3, %xmm3
18801880
; KNL-NEXT: vinserti128 $1, %xmm3, %ymm2, %ymm2
1881-
; KNL-NEXT: vpcmpeqb %ymm0, %ymm2, %ymm0
1882-
; KNL-NEXT: vpternlogq $15, %zmm0, %zmm0, %zmm0
1881+
; KNL-NEXT: vpcmpeqb %ymm0, %ymm2, %ymm2
1882+
; KNL-NEXT: vpternlogq $15, %zmm2, %zmm2, %zmm2
18831883
; KNL-NEXT: cmpb $0, 736(%rbp)
18841884
; KNL-NEXT: vmovdqa %ymm0, {{[0-9]+}}(%rsp)
1885+
; KNL-NEXT: vmovdqa %ymm2, {{[0-9]+}}(%rsp)
18851886
; KNL-NEXT: vmovdqa64 %zmm1, (%rsp)
18861887
; KNL-NEXT: setne (%rsp,%rax)
18871888
; 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)