@@ -157,8 +157,6 @@ void Rationalizer::RewriteNodeAsCall(GenTree** use,
157
157
// Replace "tree" with "call"
158
158
if (parents.Height () > 1 )
159
159
{
160
- GenTree* tmpInsertionPoint = insertionPoint;
161
-
162
160
if (tmpNum != BAD_VAR_NUM)
163
161
{
164
162
result = comp->gtNewLclvNode (tmpNum, retType);
@@ -169,18 +167,17 @@ void Rationalizer::RewriteNodeAsCall(GenTree** use,
169
167
#if defined(FEATURE_HW_INTRINSICS)
170
168
// No managed call returns TYP_MASK, so convert it from a TYP_SIMD
171
169
172
- var_types simdType = tree->TypeGet ();
173
- assert (varTypeIsSIMD (simdType));
174
-
175
170
unsigned simdSize;
176
171
CorInfoType simdBaseJitType = comp->getBaseJitTypeAndSizeOfSIMDType (call->gtRetClsHnd , &simdSize);
177
172
assert (simdSize != 0 );
178
173
179
- GenTree* cvtNode = comp->gtNewSimdCvtVectorToMaskNode (TYP_MASK, result, simdBaseJitType, simdSize);
180
- BlockRange ().InsertAfter (insertionPoint, LIR::Range (comp->fgSetTreeSeq (cvtNode), cvtNode));
181
- result = cvtNode;
174
+ result = comp->gtNewSimdCvtVectorToMaskNode (TYP_MASK, result, simdBaseJitType, simdSize);
182
175
183
- tmpInsertionPoint = result;
176
+ if (tmpNum == BAD_VAR_NUM)
177
+ {
178
+ // Propagate flags of "call" to its parent.
179
+ result->gtFlags |= (call->gtFlags & GTF_ALL_EFFECT) | GTF_CALL;
180
+ }
184
181
#else
185
182
unreached ();
186
183
#endif // FEATURE_HW_INTRINSICS
@@ -190,27 +187,44 @@ void Rationalizer::RewriteNodeAsCall(GenTree** use,
190
187
191
188
if (tmpNum != BAD_VAR_NUM)
192
189
{
190
+ // We have a return buffer, so we need to insert both the result and the call
191
+ // since they are independent trees. If we have a convert node, it will indirectly
192
+ // insert the local node.
193
+
194
+ comp->gtSetEvalOrder (result);
195
+ BlockRange ().InsertAfter (insertionPoint, LIR::Range (comp->fgSetTreeSeq (result), result));
196
+
197
+ comp->gtSetEvalOrder (call);
198
+ BlockRange ().InsertAfter (insertionPoint, LIR::Range (comp->fgSetTreeSeq (call), call));
199
+ }
200
+ else
201
+ {
202
+ // We don't have a return buffer, so we only need to insert the result, which
203
+ // will indirectly insert the call in the case we have a convert node as well.
204
+
193
205
comp->gtSetEvalOrder (result);
194
- BlockRange ().InsertAfter (tmpInsertionPoint , LIR::Range (comp->fgSetTreeSeq (result), result));
206
+ BlockRange ().InsertAfter (insertionPoint , LIR::Range (comp->fgSetTreeSeq (result), result));
195
207
}
196
208
}
197
209
else
198
210
{
199
211
// If there's no parent, the tree being replaced is the root of the
200
212
// statement (and no special handling is necessary).
201
213
*use = result;
202
- }
203
214
204
- comp->gtSetEvalOrder (call);
205
- BlockRange ().InsertAfter (insertionPoint, LIR::Range (comp->fgSetTreeSeq (call), call));
215
+ comp->gtSetEvalOrder (call);
216
+ BlockRange ().InsertAfter (insertionPoint, LIR::Range (comp->fgSetTreeSeq (call), call));
217
+ }
206
218
207
- if (result == call )
219
+ if (tmpNum == BAD_VAR_NUM )
208
220
{
209
221
// Propagate flags of "call" to its parents.
222
+ GenTreeFlags callFlags = (call->gtFlags & GTF_ALL_EFFECT) | GTF_CALL;
223
+
210
224
// 0 is current node, so start at 1
211
225
for (int i = 1 ; i < parents.Height (); i++)
212
226
{
213
- parents.Top (i)->gtFlags |= (call-> gtFlags & GTF_ALL_EFFECT) | GTF_CALL ;
227
+ parents.Top (i)->gtFlags |= callFlags ;
214
228
}
215
229
}
216
230
else
0 commit comments