-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[DAGCombiner, NVPTX] Port 'rem' custom combine from NVPTX to generic combiner #167147
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
base: main
Are you sure you want to change the base?
Changes from all commits
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 | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -900,6 +900,41 @@ namespace { | |||||||||
| ISD::NodeType ExtType); | ||||||||||
| }; | ||||||||||
|
|
||||||||||
| /// Generic remainder optimization : Folds a remainder operation (A % B) by reusing the computed quotient (A / B). | ||||||||||
| static SDValue PerformREMCombineGeneric(SDNode *N, DAGCombiner &DC, | ||||||||||
|
Contributor
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. Passing in DAGCombiner is strange, pass in the DAG and TLI, or just move to be a DAGCombiner member? |
||||||||||
| CodeGenOptLevel OptLevel) { | ||||||||||
| assert(N->getOpcode() == ISD::SREM || N->getOpcode() == ISD::UREM); | ||||||||||
|
|
||||||||||
| // Don't do anything at less than -O2. | ||||||||||
| if (OptLevel < CodeGenOptLevel::Default) | ||||||||||
| return SDValue(); | ||||||||||
|
Collaborator
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. why is this necessary? |
||||||||||
|
|
||||||||||
| SelectionDAG &DAG = DC.getDAG(); | ||||||||||
| SDLoc DL(N); | ||||||||||
| EVT VT = N->getValueType(0); | ||||||||||
| bool IsSigned = N->getOpcode() == ISD::SREM; | ||||||||||
| unsigned DivOpc = IsSigned ? ISD::SDIV : ISD::UDIV; | ||||||||||
|
|
||||||||||
| const SDValue &Num = N->getOperand(0); | ||||||||||
| const SDValue &Den = N->getOperand(1); | ||||||||||
|
Comment on lines
+918
to
+919
Contributor
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.
Suggested change
|
||||||||||
|
|
||||||||||
| AttributeList Attr = DC.getDAG().getMachineFunction().getFunction().getAttributes(); | ||||||||||
|
Contributor
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.
Suggested change
|
||||||||||
| if (DC.getDAG().getTargetLoweringInfo().isIntDivCheap(N->getValueType(0), Attr)) | ||||||||||
| return SDValue(); | ||||||||||
|
|
||||||||||
| for (const SDNode *U : Num->users()) { | ||||||||||
| if (U->getOpcode() == DivOpc && U->getOperand(0) == Num && | ||||||||||
| U->getOperand(1) == Den) { | ||||||||||
| // Num % Den -> Num - (Num / Den) * Den | ||||||||||
| return DAG.getNode(ISD::SUB, DL, VT, Num, | ||||||||||
| DAG.getNode(ISD::MUL, DL, VT, | ||||||||||
| DAG.getNode(DivOpc, DL, VT, Num, Den), | ||||||||||
| Den)); | ||||||||||
|
Comment on lines
+930
to
+932
Contributor
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. Use temporary variables to reduce ugly line wrap |
||||||||||
| } | ||||||||||
| } | ||||||||||
| return SDValue(); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| /// This class is a DAGUpdateListener that removes any deleted | ||||||||||
| /// nodes from the worklist. | ||||||||||
| class WorklistRemover : public SelectionDAG::DAGUpdateListener { | ||||||||||
|
|
@@ -5400,6 +5435,9 @@ SDValue DAGCombiner::visitREM(SDNode *N) { | |||||||||
| if (SDValue NewSel = foldBinOpIntoSelect(N)) | ||||||||||
| return NewSel; | ||||||||||
|
|
||||||||||
| if (SDValue V = PerformREMCombineGeneric(N, *this, OptLevel)) | ||||||||||
| return V; | ||||||||||
|
|
||||||||||
| if (isSigned) { | ||||||||||
| // If we know the sign bits of both operands are zero, strength reduce to a | ||||||||||
| // urem instead. Handles (X & 0x0FFFFFFF) %s 16 -> X&15 | ||||||||||
|
|
||||||||||
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.