Skip to content

Commit a5e4371

Browse files
nikicveselypeta
authored andcommitted
[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/llvm-project#63055. Differential Revision: https://reviews.llvm.org/D151883
2 parents e04855c + e506bfa commit a5e4371

File tree

3 files changed

+24
-14
lines changed

3 files changed

+24
-14
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2470,6 +2470,16 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
24702470
ISD::CondCode Cond, const SDLoc &dl) {
24712471
EVT OpVT = N1.getValueType();
24722472

2473+
auto GetUndefBooleanConstant = [&]() {
2474+
if (VT.getScalarType() == MVT::i1 ||
2475+
TLI->getBooleanContents(OpVT) ==
2476+
TargetLowering::UndefinedBooleanContent)
2477+
return getUNDEF(VT);
2478+
// ZeroOrOne / ZeroOrNegative require specific values for the high bits,
2479+
// so we cannot use getUNDEF(). Return zero instead.
2480+
return getConstant(0, dl, VT);
2481+
};
2482+
24732483
// These setcc operations always fold.
24742484
switch (Cond) {
24752485
default: break;
@@ -2499,12 +2509,12 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
24992509
// icmp eq/ne X, undef -> undef.
25002510
if ((N1.isUndef() || N2.isUndef()) &&
25012511
(Cond == ISD::SETEQ || Cond == ISD::SETNE))
2502-
return getUNDEF(VT);
2512+
return GetUndefBooleanConstant();
25032513

25042514
// If both operands are undef, we can return undef for int comparison.
25052515
// icmp undef, undef -> undef.
25062516
if (N1.isUndef() && N2.isUndef())
2507-
return getUNDEF(VT);
2517+
return GetUndefBooleanConstant();
25082518

25092519
// icmp X, X -> true/false
25102520
// icmp X, undef -> true/false because undef could be X.
@@ -2530,34 +2540,34 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
25302540
switch (Cond) {
25312541
default: break;
25322542
case ISD::SETEQ: if (R==APFloat::cmpUnordered)
2533-
return getUNDEF(VT);
2543+
return GetUndefBooleanConstant();
25342544
[[fallthrough]];
25352545
case ISD::SETOEQ: return getBoolConstant(R==APFloat::cmpEqual, dl, VT,
25362546
OpVT);
25372547
case ISD::SETNE: if (R==APFloat::cmpUnordered)
2538-
return getUNDEF(VT);
2548+
return GetUndefBooleanConstant();
25392549
[[fallthrough]];
25402550
case ISD::SETONE: return getBoolConstant(R==APFloat::cmpGreaterThan ||
25412551
R==APFloat::cmpLessThan, dl, VT,
25422552
OpVT);
25432553
case ISD::SETLT: if (R==APFloat::cmpUnordered)
2544-
return getUNDEF(VT);
2554+
return GetUndefBooleanConstant();
25452555
[[fallthrough]];
25462556
case ISD::SETOLT: return getBoolConstant(R==APFloat::cmpLessThan, dl, VT,
25472557
OpVT);
25482558
case ISD::SETGT: if (R==APFloat::cmpUnordered)
2549-
return getUNDEF(VT);
2559+
return GetUndefBooleanConstant();
25502560
[[fallthrough]];
25512561
case ISD::SETOGT: return getBoolConstant(R==APFloat::cmpGreaterThan, dl,
25522562
VT, OpVT);
25532563
case ISD::SETLE: if (R==APFloat::cmpUnordered)
2554-
return getUNDEF(VT);
2564+
return GetUndefBooleanConstant();
25552565
[[fallthrough]];
25562566
case ISD::SETOLE: return getBoolConstant(R==APFloat::cmpLessThan ||
25572567
R==APFloat::cmpEqual, dl, VT,
25582568
OpVT);
25592569
case ISD::SETGE: if (R==APFloat::cmpUnordered)
2560-
return getUNDEF(VT);
2570+
return GetUndefBooleanConstant();
25612571
[[fallthrough]];
25622572
case ISD::SETOGE: return getBoolConstant(R==APFloat::cmpGreaterThan ||
25632573
R==APFloat::cmpEqual, dl, VT, OpVT);
@@ -2602,7 +2612,7 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
26022612
case 1: // Known true.
26032613
return getBoolConstant(true, dl, VT, OpVT);
26042614
case 2: // Undefined.
2605-
return getUNDEF(VT);
2615+
return GetUndefBooleanConstant();
26062616
}
26072617
}
26082618

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

Lines changed: 3 additions & 2 deletions
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

Lines changed: 2 additions & 3 deletions
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)