return op1->AsOp();
}
-//------------------------------------------------------------------------------
-// fgMorphCastedBitwiseOp : Try to simplify "(T)x op (T)y" to "(T)(x op y)".
-//
-// Arguments:
-// tree - node to fold
-//
-// Return Value:
-// A folded GenTree* instance, or nullptr if it couldn't be folded
-GenTree* Compiler::fgMorphCastedBitwiseOp(GenTreeOp* tree)
-{
- // This transform does not preserve VNs and deletes a node.
- assert(fgGlobalMorph);
- assert(varTypeIsIntegralOrI(tree));
- assert(tree->OperIs(GT_OR, GT_AND, GT_XOR));
-
- GenTree* op1 = tree->gtGetOp1();
- GenTree* op2 = tree->gtGetOp2();
- genTreeOps oper = tree->OperGet();
-
- // see whether both ops are casts, with matching to and from types.
- if (op1->OperIs(GT_CAST) && op2->OperIs(GT_CAST))
- {
- // bail if either operand is a checked cast
- if (op1->gtOverflow() || op2->gtOverflow())
- {
- return nullptr;
- }
-
- var_types fromType = op1->AsCast()->CastOp()->TypeGet();
- var_types toType = op1->AsCast()->CastToType();
- bool isUnsigned = op1->IsUnsigned();
-
- if (varTypeIsFloating(fromType) || (op2->CastFromType() != fromType) || (op2->CastToType() != toType) ||
- (op2->IsUnsigned() != isUnsigned))
- {
- return nullptr;
- }
-
- /*
- // Reuse gentree nodes:
- //
- // tree op1
- // / \ |
- // op1 op2 ==> tree
- // | | / \.
- // x y x y
- //
- // (op2 becomes garbage)
- */
-
- tree->gtOp1 = op1->AsCast()->CastOp();
- tree->gtOp2 = op2->AsCast()->CastOp();
- tree->gtType = genActualType(fromType);
-
- op1->gtType = genActualType(toType);
- op1->AsCast()->gtOp1 = tree;
- op1->AsCast()->CastToType() = toType;
- op1->SetAllEffectsFlags(tree);
- // no need to update isUnsigned
-
- DEBUG_DESTROY_NODE(op2);
- INDEBUG(op1->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED);
-
- return op1;
- }
-
- return nullptr;
-}
-
//------------------------------------------------------------------------
// fgMorphSmpOp: morph a GTK_SMPOP tree
//
}
}
- if (fgGlobalMorph && tree->OperIs(GT_AND, GT_OR, GT_XOR))
- {
- GenTree* castTree = fgMorphCastedBitwiseOp(tree->AsOp());
- if (castTree != nullptr)
- {
- return castTree;
- }
- }
-
if (varTypeIsIntegralOrI(tree))
{
genTreeOps oldTreeOper = tree->OperGet();