private void EmitBranchComparison(bool branch, BinaryExpression node, Label label) { Debug.Assert(node.NodeType == ExpressionType.Equal || node.NodeType == ExpressionType.NotEqual); Debug.Assert(!node.IsLiftedToNull); // To share code paths, we want to treat NotEqual as an inverted Equal var branchWhenEqual = branch == (node.NodeType == ExpressionType.Equal); if (node.Method != null) { EmitBinaryMethod(node, CompilationFlags.EmitAsNoTail); // EmitBinaryMethod takes into account the Equal/NotEqual // node kind, so use the original branch value EmitBranchOp(branch, label); } else if (ConstantCheck.IsNull(node.Left)) { if (node.Right.Type.IsNullableType()) { EmitAddress(node.Right, node.Right.Type); _ilg.EmitHasValue(node.Right.Type); } else { Debug.Assert(!node.Right.Type.IsValueType); EmitExpression(GetEqualityOperand(node.Right)); } EmitBranchOp(!branchWhenEqual, label); } else if (ConstantCheck.IsNull(node.Right)) { if (node.Left.Type.IsNullableType()) { EmitAddress(node.Left, node.Left.Type); _ilg.EmitHasValue(node.Left.Type); } else { Debug.Assert(!node.Left.Type.IsValueType); EmitExpression(GetEqualityOperand(node.Left)); } EmitBranchOp(!branchWhenEqual, label); } else if (node.Left.Type.IsNullableType() || node.Right.Type.IsNullableType()) { EmitBinaryExpression(node); // EmitBinaryExpression takes into account the Equal/NotEqual // node kind, so use the original branch value EmitBranchOp(branch, label); } else { EmitExpression(GetEqualityOperand(node.Left)); EmitExpression(GetEqualityOperand(node.Right)); if (branchWhenEqual) { _ilg.Emit(OpCodes.Beq, label); } else { _ilg.Emit(OpCodes.Ceq); _ilg.Emit(OpCodes.Brfalse, label); } } }