-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Optimize FMA codegen base on the overwritten #58196
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
Changes from 1 commit
ee2c0b6
46d0011
cce4bda
b825291
f615e39
b698036
7d9c0d6
1344d92
029a9b5
f2a371f
9955389
7c56653
1d51caa
091133e
9a6ae44
ffcff76
5641f8f
b7312ac
a325fe3
0f950dd
33a596d
5da9368
c3a9f07
9e356aa
f8159bc
18bbe4d
2ca2524
17bd967
eed5912
43c5034
5ef70a5
bfa6924
12f260b
5ca658e
ec4ef66
aa93a85
c66a018
ff5a433
a4657c7
75d7a37
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6313,35 +6313,39 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) | |
| { | ||
| if ((intrinsicId >= NI_FMA_MultiplyAdd) && (intrinsicId <= NI_FMA_MultiplySubtractNegatedScalar)) | ||
| { | ||
| bool supportsRegOptional = false; | ||
| bool supportsRegOptional2 = false; | ||
| unsigned resultOpNum = 0; | ||
| bool supportsRegOptional = false; | ||
| unsigned overwrittenOpNum = 0; | ||
| LIR::Use use; | ||
|
|
||
| if (BlockRange().TryGetUse(node, &use)) | ||
| { | ||
| resultOpNum = node->GetResultOpNumForFMA(use.User(), op1, op2, op3); | ||
| overwrittenOpNum = node->GetResultOpNumForFMA(use.User(), op1, op2, op3); | ||
|
||
| } | ||
|
|
||
| if (resultOpNum != 1 && IsContainableHWIntrinsicOp(node, op1, &supportsRegOptional) && | ||
| if (overwrittenOpNum != 1 && IsContainableHWIntrinsicOp(node, op1, &supportsRegOptional) && | ||
|
||
| !HWIntrinsicInfo::CopiesUpperBits(intrinsicId)) | ||
| { | ||
| // result = ([op1] * op2) + op3 | ||
| MakeSrcContained(node, op1); | ||
| } | ||
| else if (resultOpNum != 2 && IsContainableHWIntrinsicOp(node, op2, &supportsRegOptional2)) | ||
| else if (overwrittenOpNum != 2 && IsContainableHWIntrinsicOp(node, op2, &supportsRegOptional)) | ||
| { | ||
| // result = (op1 * [op2]) + op3 | ||
| MakeSrcContained(node, op2); | ||
| } | ||
| else if (resultOpNum != 3 && IsContainableHWIntrinsicOp(node, op3, &supportsRegOptional)) | ||
| else if (overwrittenOpNum != 3 && IsContainableHWIntrinsicOp(node, op3, &supportsRegOptional)) | ||
| { | ||
| // result = (op1 * op2) + [op3] | ||
| MakeSrcContained(node, op3); | ||
| } | ||
| else if (resultOpNum == 3) | ||
| else if (overwrittenOpNum != 1 && !HWIntrinsicInfo::CopiesUpperBits(intrinsicId)) | ||
| { | ||
| assert(supportsRegOptional2); | ||
| assert(supportsRegOptional); | ||
| op1->SetRegOptional(); | ||
| } | ||
| else if (overwrittenOpNum != 2) | ||
| { | ||
| assert(supportsRegOptional); | ||
| op2->SetRegOptional(); | ||
| } | ||
| else | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2368,7 +2368,7 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree) | |
| tgtPrefUse = BuildUse(op2); | ||
| srcCount += 1; | ||
|
|
||
| if (op1->isContained()) | ||
| if (op1->isContained() || op1->IsRegOptional()) | ||
| { | ||
| // op2 = ([op1] * op2) + op3 | ||
| srcCount += BuildOperandUses(op1); | ||
|
|
@@ -2386,7 +2386,7 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree) | |
| tgtPrefUse = BuildUse(op3); | ||
| srcCount += 1; | ||
|
|
||
| if (op1->isContained()) | ||
| if (op1->isContained() || op1->IsRegOptional()) | ||
| { | ||
| // op3 = ([op1] * op2) + op3 | ||
| srcCount += BuildOperandUses(op1); | ||
|
|
@@ -2402,10 +2402,10 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree) | |
| else | ||
| { | ||
| assert(resultOpNum == 0); | ||
| if (op1->isContained()) | ||
| if (op1->isContained() || op1->IsRegOptional()) | ||
| { | ||
| // In the case that result is writtent into destination that is different from any of the | ||
|
||
| // source operands, we set op2 to be tgtPrefUse when op1 is contained. | ||
| // source operands, we set op2 to be tgtPrefUse when op1 is contained. | ||
|
|
||
| tgtPrefUse = BuildUse(op2); | ||
| srcCount += 1; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.