-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[NVPTX] Fix lowering of i1 SETCC #115035
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[NVPTX] Fix lowering of i1 SETCC #115035
Changes from all commits
beedad9
13a383f
83a7e42
980ea86
c8da53d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11889,6 +11889,47 @@ bool TargetLowering::LegalizeSetCCCondCode(SelectionDAG &DAG, EVT VT, | |
return true; | ||
} | ||
|
||
// Special case: expand i1 comparisons using logical operations. | ||
if (OpVT == MVT::i1) { | ||
SDValue Ret; | ||
switch (CCCode) { | ||
default: | ||
llvm_unreachable("Unknown integer setcc!"); | ||
case ISD::SETEQ: // X == Y --> ~(X ^ Y) | ||
Ret = DAG.getNOT(dl, DAG.getNode(ISD::XOR, dl, MVT::i1, LHS, RHS), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this need to be guarded by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd prefer not to. NVPTX is the only target using these expansions and we don't have any way to expand if not. I don't see what the point of adding them would be. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My question boils down to: will My assumption was no, but based on your answer, I'm gathering that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the issue here is that there's more than one possible interpretation of "lower SetCC(i1) differently". NVPTX can do it via logical ops on predicates, other targets may not. On other targets it may be something else. Whoever would use "setCondCodeAction(...,Expand)" would have no idea what it would expand into. This should at least be documented. If/when we would encounter a target which would have a different way of expanding setcc, we would probably need a more nuanced hint to tell LLVM which flavor we actually want. I think at the moment only Hexagon uses |
||
MVT::i1); | ||
break; | ||
case ISD::SETNE: // X != Y --> (X ^ Y) | ||
Ret = DAG.getNode(ISD::XOR, dl, MVT::i1, LHS, RHS); | ||
break; | ||
case ISD::SETGT: // X >s Y --> X == 0 & Y == 1 --> ~X & Y | ||
case ISD::SETULT: // X <u Y --> X == 0 & Y == 1 --> ~X & Y | ||
Ret = DAG.getNode(ISD::AND, dl, MVT::i1, RHS, | ||
DAG.getNOT(dl, LHS, MVT::i1)); | ||
break; | ||
case ISD::SETLT: // X <s Y --> X == 1 & Y == 0 --> ~Y & X | ||
case ISD::SETUGT: // X >u Y --> X == 1 & Y == 0 --> ~Y & X | ||
Ret = DAG.getNode(ISD::AND, dl, MVT::i1, LHS, | ||
DAG.getNOT(dl, RHS, MVT::i1)); | ||
break; | ||
case ISD::SETULE: // X <=u Y --> X == 0 | Y == 1 --> ~X | Y | ||
case ISD::SETGE: // X >=s Y --> X == 0 | Y == 1 --> ~X | Y | ||
Ret = DAG.getNode(ISD::OR, dl, MVT::i1, RHS, | ||
DAG.getNOT(dl, LHS, MVT::i1)); | ||
break; | ||
case ISD::SETUGE: // X >=u Y --> X == 1 | Y == 0 --> ~Y | X | ||
case ISD::SETLE: // X <=s Y --> X == 1 | Y == 0 --> ~Y | X | ||
Ret = DAG.getNode(ISD::OR, dl, MVT::i1, LHS, | ||
DAG.getNOT(dl, RHS, MVT::i1)); | ||
break; | ||
} | ||
|
||
LHS = DAG.getZExtOrTrunc(Ret, dl, VT); | ||
RHS = SDValue(); | ||
CC = SDValue(); | ||
justinfargnoli marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return true; | ||
} | ||
|
||
ISD::CondCode CC1 = ISD::SETCC_INVALID, CC2 = ISD::SETCC_INVALID; | ||
unsigned Opc = 0; | ||
switch (CCCode) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this need the type special case? LegalizeSetCCCondCode should do as asked regardless of the type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logical simplifications we're using to expand setcc for i1 will not be correct for larger types.
In theory yes, but this isn't the case today, and creating a valid expansion for all types x cond-codes would be a time consuming way to add a lot of in practice dead code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a more specific example for "not correct for larger types"? It's not an arbitrary wide typed value. The result conforms to getTargetBooleanContents, which in turn should respect all of the logical expansions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of these expansions take advantage of the unique nature of the i1 type. For example consider signed greater than, this will only be true for i1s if and only if the first operand is 0 and the second is -1, hence it can be expressed as ~X & Y. This sort of bit manipulation is of course totally invalid for any larger type.
To see that this transformation is okay for i1, and not for a larger type here is an alive2 where the transform has been expressed on llvm IR: https://alive2.llvm.org/ce/z/6jS_rA