use of org.graalvm.compiler.nodes.calc.FloatNormalizeCompareNode in project graal by oracle.
the class IfNode method canonicalizeConditionalCascade.
private ValueNode canonicalizeConditionalCascade(SimplifierTool tool, ValueNode trueValue, ValueNode falseValue) {
if (trueValue.getStackKind() != falseValue.getStackKind()) {
return null;
}
if (trueValue.getStackKind() != JavaKind.Int && trueValue.getStackKind() != JavaKind.Long) {
return null;
}
if (isSafeConditionalInput(trueValue, trueSuccessor) && isSafeConditionalInput(falseValue, falseSuccessor)) {
return graph().unique(new ConditionalNode(condition(), trueValue, falseValue));
}
ValueNode value = canonicalizeConditionalViaImplies(trueValue, falseValue);
if (value != null) {
return value;
}
if (graph().isBeforeStage(StageFlag.EXPAND_LOGIC)) {
/*
* !isAfterExpandLogic() => Cannot spawn NormalizeCompareNodes after lowering in the
* ExpandLogicPhase.
*/
ConditionalNode conditional = null;
ValueNode constant = null;
boolean negateCondition;
if (trueValue instanceof ConditionalNode && falseValue.isConstant()) {
conditional = (ConditionalNode) trueValue;
constant = falseValue;
negateCondition = true;
} else if (falseValue instanceof ConditionalNode && trueValue.isConstant()) {
conditional = (ConditionalNode) falseValue;
constant = trueValue;
negateCondition = false;
} else {
return null;
}
boolean negateConditionalCondition = false;
ValueNode otherValue = null;
if (constant == conditional.trueValue()) {
otherValue = conditional.falseValue();
negateConditionalCondition = false;
} else if (constant == conditional.falseValue()) {
otherValue = conditional.trueValue();
negateConditionalCondition = true;
}
if (otherValue != null && otherValue.isConstant()) {
BranchProbabilityData shortCutProbability = trueSuccessorProfile();
LogicNode newCondition = LogicNode.or(condition(), negateCondition, conditional.condition(), negateConditionalCondition, shortCutProbability);
return graph().unique(new ConditionalNode(newCondition, constant, otherValue));
}
if (constant.isJavaConstant() && conditional.trueValue().isJavaConstant() && conditional.falseValue().isJavaConstant() && condition() instanceof CompareNode && conditional.condition() instanceof CompareNode) {
CompareNode condition1 = (CompareNode) condition();
Condition cond1 = condition1.condition().asCondition();
if (negateCondition) {
cond1 = cond1.negate();
}
// cond1 is EQ, NE, LT, or GE
CompareNode condition2 = (CompareNode) conditional.condition();
Condition cond2 = condition2.condition().asCondition();
ValueNode x = condition1.getX();
ValueNode y = condition1.getY();
ValueNode x2 = condition2.getX();
ValueNode y2 = condition2.getY();
// `x cond1 y ? c1 : (x2 cond2 y2 ? c2 : c3)`
boolean sameVars = x == x2 && y == y2;
if (!sameVars && x == y2 && y == x2) {
sameVars = true;
cond2 = cond2.mirror();
}
if (sameVars) {
JavaKind stackKind = conditional.trueValue().stamp(NodeView.from(tool)).getStackKind();
assert !stackKind.isNumericFloat();
long c1 = constant.asJavaConstant().asLong();
long c2 = conditional.trueValue().asJavaConstant().asLong();
long c3 = conditional.falseValue().asJavaConstant().asLong();
// canonicalize cond2
cond2 = cond2.join(cond1.negate());
if (cond2 == null) {
// mixing signed and unsigned cases, or useless combination of conditions
return null;
}
// derive cond3 from cond1 and cond2
Condition cond3 = cond1.negate().join(cond2.negate());
if (cond3 == null) {
// mixing signed and unsigned cases, or useless combination of conditions
return null;
}
boolean unsigned = cond1.isUnsigned() || cond2.isUnsigned();
boolean floatingPoint = x.stamp(NodeView.from(tool)) instanceof FloatStamp;
assert !floatingPoint || y.stamp(NodeView.from(tool)) instanceof FloatStamp;
assert !(floatingPoint && unsigned);
long expected1 = expectedConstantForNormalize(cond1);
long expected2 = expectedConstantForNormalize(cond2);
long expected3 = expectedConstantForNormalize(cond3);
if (c1 == expected1 && c2 == expected2 && c3 == expected3) {
// normal order
} else if (c1 == 0 - expected1 && c2 == 0 - expected2 && c3 == 0 - expected3) {
// reverse order
ValueNode tmp = x;
x = y;
y = tmp;
} else {
// cannot be expressed by NormalizeCompareNode
return null;
}
if (floatingPoint) {
boolean unorderedLess = false;
if (((FloatStamp) x.stamp).canBeNaN() || ((FloatStamp) y.stamp).canBeNaN()) {
// we may encounter NaNs, check the unordered value
// (following the original condition's "unorderedIsTrue" path)
long unorderedValue = condition1.unorderedIsTrue() ? c1 : condition2.unorderedIsTrue() ? c2 : c3;
if (unorderedValue == 0) {
// returning "0" for unordered is not possible
return null;
}
unorderedLess = unorderedValue == -1;
}
return graph().unique(new FloatNormalizeCompareNode(x, y, stackKind, unorderedLess));
} else {
return graph().unique(new IntegerNormalizeCompareNode(x, y, stackKind, unsigned));
}
}
}
}
return null;
}
Aggregations