Skip to content

Commit

Permalink
[SDAG] Fix incorrect use of undef for boolean contents (PR63055)
Browse files Browse the repository at this point in the history
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 #63055.

Differential Revision: https://reviews.llvm.org/D151883
  • Loading branch information
nikic committed Jun 1, 2023
1 parent 3ddd186 commit e506bfa
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 14 deletions.
28 changes: 19 additions & 9 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2436,6 +2436,16 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
ISD::CondCode Cond, const SDLoc &dl) {
EVT OpVT = N1.getValueType();

auto GetUndefBooleanConstant = [&]() {
if (VT.getScalarType() == MVT::i1 ||
TLI->getBooleanContents(OpVT) ==
TargetLowering::UndefinedBooleanContent)
return getUNDEF(VT);
// ZeroOrOne / ZeroOrNegative require specific values for the high bits,
// so we cannot use getUNDEF(). Return zero instead.
return getConstant(0, dl, VT);
};

// These setcc operations always fold.
switch (Cond) {
default: break;
Expand Down Expand Up @@ -2465,12 +2475,12 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
// icmp eq/ne X, undef -> undef.
if ((N1.isUndef() || N2.isUndef()) &&
(Cond == ISD::SETEQ || Cond == ISD::SETNE))
return getUNDEF(VT);
return GetUndefBooleanConstant();

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

// icmp X, X -> true/false
// icmp X, undef -> true/false because undef could be X.
Expand All @@ -2496,34 +2506,34 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
switch (Cond) {
default: break;
case ISD::SETEQ: if (R==APFloat::cmpUnordered)
return getUNDEF(VT);
return GetUndefBooleanConstant();
[[fallthrough]];
case ISD::SETOEQ: return getBoolConstant(R==APFloat::cmpEqual, dl, VT,
OpVT);
case ISD::SETNE: if (R==APFloat::cmpUnordered)
return getUNDEF(VT);
return GetUndefBooleanConstant();
[[fallthrough]];
case ISD::SETONE: return getBoolConstant(R==APFloat::cmpGreaterThan ||
R==APFloat::cmpLessThan, dl, VT,
OpVT);
case ISD::SETLT: if (R==APFloat::cmpUnordered)
return getUNDEF(VT);
return GetUndefBooleanConstant();
[[fallthrough]];
case ISD::SETOLT: return getBoolConstant(R==APFloat::cmpLessThan, dl, VT,
OpVT);
case ISD::SETGT: if (R==APFloat::cmpUnordered)
return getUNDEF(VT);
return GetUndefBooleanConstant();
[[fallthrough]];
case ISD::SETOGT: return getBoolConstant(R==APFloat::cmpGreaterThan, dl,
VT, OpVT);
case ISD::SETLE: if (R==APFloat::cmpUnordered)
return getUNDEF(VT);
return GetUndefBooleanConstant();
[[fallthrough]];
case ISD::SETOLE: return getBoolConstant(R==APFloat::cmpLessThan ||
R==APFloat::cmpEqual, dl, VT,
OpVT);
case ISD::SETGE: if (R==APFloat::cmpUnordered)
return getUNDEF(VT);
return GetUndefBooleanConstant();
[[fallthrough]];
case ISD::SETOGE: return getBoolConstant(R==APFloat::cmpGreaterThan ||
R==APFloat::cmpEqual, dl, VT, OpVT);
Expand Down Expand Up @@ -2568,7 +2578,7 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2,
case 1: // Known true.
return getBoolConstant(true, dl, VT, OpVT);
case 2: // Undefined.
return getUNDEF(VT);
return GetUndefBooleanConstant();
}
}

Expand Down
5 changes: 3 additions & 2 deletions llvm/test/CodeGen/X86/avx512-insert-extract.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1878,10 +1878,11 @@ define i96 @test_insertelement_variable_v96i1(<96 x i8> %a, i8 %b, i32 %index) n
; KNL-NEXT: vpinsrb $14, 720(%rbp), %xmm3, %xmm3
; KNL-NEXT: vpinsrb $15, 728(%rbp), %xmm3, %xmm3
; KNL-NEXT: vinserti128 $1, %xmm3, %ymm2, %ymm2
; KNL-NEXT: vpcmpeqb %ymm0, %ymm2, %ymm0
; KNL-NEXT: vpternlogq $15, %zmm0, %zmm0, %zmm0
; KNL-NEXT: vpcmpeqb %ymm0, %ymm2, %ymm2
; KNL-NEXT: vpternlogq $15, %zmm2, %zmm2, %zmm2
; KNL-NEXT: cmpb $0, 736(%rbp)
; KNL-NEXT: vmovdqa %ymm0, {{[0-9]+}}(%rsp)
; KNL-NEXT: vmovdqa %ymm2, {{[0-9]+}}(%rsp)
; KNL-NEXT: vmovdqa64 %zmm1, (%rsp)
; KNL-NEXT: setne (%rsp,%rax)
; KNL-NEXT: vpmovsxbd (%rsp), %zmm0
Expand Down
5 changes: 2 additions & 3 deletions llvm/test/CodeGen/X86/setcc.ll
Original file line number Diff line number Diff line change
Expand Up @@ -339,17 +339,16 @@ define i32 @PR55138(i32 %x) {
ret i32 %and
}

; FIXME: Miscompile.
define i64 @pr63055(double %arg) {
; X86-LABEL: pr63055:
; X86: ## %bb.0:
; X86-NEXT: movl $255, %eax
; X86-NEXT: movl $1, %eax
; X86-NEXT: xorl %edx, %edx
; X86-NEXT: retl
;
; X64-LABEL: pr63055:
; X64: ## %bb.0:
; X64-NEXT: movl $255, %eax
; X64-NEXT: movl $1, %eax
; X64-NEXT: retq
%fcmp = fcmp une double 0x7FF8000000000000, %arg
%ext = zext i1 %fcmp to i64
Expand Down

0 comments on commit e506bfa

Please sign in to comment.