001/*
002 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.compiler.test;
024
025import org.junit.*;
026
027import com.oracle.graal.nodes.*;
028import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
029import com.oracle.graal.phases.common.*;
030import com.oracle.graal.phases.tiers.*;
031
032public class IntegerEqualsCanonicalizerTest extends GraalCompilerTest {
033
034    @Test
035    public void testShiftEquals() {
036        /*
037         * tests the canonicalization of (x >>> const) == 0 to x |test| (-1 << const)
038         */
039        test("testShiftEqualsSnippet", "testShiftEqualsReference");
040    }
041
042    @SuppressWarnings("unused") private static int field;
043
044    public static void testShiftEqualsSnippet(int x, int[] array, int y) {
045        // optimize
046        field = (x >>> 10) == 0 ? 1 : 0;
047        field = (array.length >> 10) == 0 ? 1 : 0;
048        field = (x << 10) == 0 ? 1 : 0;
049        // don't optimize
050        field = (x >> 10) == 0 ? 1 : 0;
051        field = (x >>> y) == 0 ? 1 : 0;
052        field = (x >> y) == 0 ? 1 : 0;
053        field = (x << y) == 0 ? 1 : 0;
054        field = (x >>> y) == 1 ? 1 : 0;
055        field = (x >> y) == 1 ? 1 : 0;
056        field = (x << y) == 1 ? 1 : 0;
057    }
058
059    public static void testShiftEqualsReference(int x, int[] array, int y) {
060        field = (x & 0xfffffc00) == 0 ? 1 : 0;
061        field = (array.length & 0xfffffc00) == 0 ? 1 : 0;
062        field = (x & 0x3fffff) == 0 ? 1 : 0;
063        // don't optimize signed right shifts
064        field = (x >> 10) == 0 ? 1 : 0;
065        // don't optimize no-constant shift amounts
066        field = (x >>> y) == 0 ? 1 : 0;
067        field = (x >> y) == 0 ? 1 : 0;
068        field = (x << y) == 0 ? 1 : 0;
069        // don't optimize non-zero comparisons
070        field = (x >>> y) == 1 ? 1 : 0;
071        field = (x >> y) == 1 ? 1 : 0;
072        field = (x << y) == 1 ? 1 : 0;
073    }
074
075    @Test
076    public void testCompare() {
077        test("testCompareSnippet", "testCompareReference");
078    }
079
080    public static void testCompareSnippet(int x, int y, int[] array1, int[] array2) {
081        int tempX = x;
082        int array1Length = array1.length;
083        int array2Length = array2.length;
084        // optimize
085        field = x == tempX ? 1 : 0;
086        field = x != tempX ? 1 : 0;
087        field = array1Length != (-1 - array2Length) ? 1 : 0;
088        field = array1Length == (-1 - array2Length) ? 1 : 0;
089        // don't optimize
090        field = x == y ? 1 : 0;
091        field = array1Length == array2Length ? 1 : 0;
092        field = array1Length == (-array2Length) ? 1 : 0;
093    }
094
095    public static void testCompareReference(int x, int y, int[] array1, int[] array2) {
096        int array1Length = array1.length;
097        int array2Length = array2.length;
098        // optimize
099        field = 1;
100        field = 0;
101        field = 1;
102        field = 0;
103        // don't optimize (overlapping value ranges)
104        field = x == y ? 1 : 0;
105        field = array1Length == array2Length ? 1 : 0;
106        field = array1Length == (-array2Length) ? 1 : 0;
107    }
108
109    private void test(String snippet, String referenceSnippet) {
110        StructuredGraph graph = getCanonicalizedGraph(snippet);
111        StructuredGraph referenceGraph = getCanonicalizedGraph(referenceSnippet);
112        assertEquals(referenceGraph, graph);
113    }
114
115    private StructuredGraph getCanonicalizedGraph(String snippet) {
116        StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
117        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
118        for (FrameState state : graph.getNodes(FrameState.TYPE).snapshot()) {
119            state.replaceAtUsages(null);
120            state.safeDelete();
121        }
122        return graph;
123    }
124}