1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker /** 18*795d594fSAndroid Build Coastguard Worker * Tests for last value of a few periodic sequences 19*795d594fSAndroid Build Coastguard Worker * (found by fuzz testing). 20*795d594fSAndroid Build Coastguard Worker */ 21*795d594fSAndroid Build Coastguard Worker public class Main { 22*795d594fSAndroid Build Coastguard Worker 23*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.doitUpInt(int) loop_optimization (before) 24*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 25*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 26*795d594fSAndroid Build Coastguard Worker // 27*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.doitUpInt(int) loop_optimization (after) 28*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi doitUpInt(int n)29*795d594fSAndroid Build Coastguard Worker static int doitUpInt(int n) { 30*795d594fSAndroid Build Coastguard Worker // Complete loop is replaced by last-value. 31*795d594fSAndroid Build Coastguard Worker int lI = 1; 32*795d594fSAndroid Build Coastguard Worker for (int i1 = 0; i1 < n; i1++) { 33*795d594fSAndroid Build Coastguard Worker lI = (1486662021 - lI); 34*795d594fSAndroid Build Coastguard Worker } 35*795d594fSAndroid Build Coastguard Worker return lI; 36*795d594fSAndroid Build Coastguard Worker } 37*795d594fSAndroid Build Coastguard Worker 38*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.doitDownInt(int) loop_optimization (before) 39*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 40*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 41*795d594fSAndroid Build Coastguard Worker // 42*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.doitDownInt(int) loop_optimization (after) 43*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi doitDownInt(int n)44*795d594fSAndroid Build Coastguard Worker static int doitDownInt(int n) { 45*795d594fSAndroid Build Coastguard Worker // Complete loop is replaced by last-value. 46*795d594fSAndroid Build Coastguard Worker int lI = 1; 47*795d594fSAndroid Build Coastguard Worker for (int i1 = n - 1; i1 >= 0; i1--) { 48*795d594fSAndroid Build Coastguard Worker lI = (1486662021 - lI); 49*795d594fSAndroid Build Coastguard Worker } 50*795d594fSAndroid Build Coastguard Worker return lI; 51*795d594fSAndroid Build Coastguard Worker } 52*795d594fSAndroid Build Coastguard Worker 53*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.doitDownInt2(int) loop_optimization (before) 54*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 55*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 56*795d594fSAndroid Build Coastguard Worker // 57*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.doitDownInt2(int) loop_optimization (after) 58*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi doitDownInt2(int n)59*795d594fSAndroid Build Coastguard Worker static int doitDownInt2(int n) { 60*795d594fSAndroid Build Coastguard Worker // Complete loop is replaced by last-value. 61*795d594fSAndroid Build Coastguard Worker int lI = 1; 62*795d594fSAndroid Build Coastguard Worker for (int i1 = n; i1 > 0; i1--) { 63*795d594fSAndroid Build Coastguard Worker lI = (1486662021 - lI); 64*795d594fSAndroid Build Coastguard Worker } 65*795d594fSAndroid Build Coastguard Worker return lI; 66*795d594fSAndroid Build Coastguard Worker } 67*795d594fSAndroid Build Coastguard Worker 68*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.doitUpFloat(int) loop_optimization (before) 69*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 70*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 71*795d594fSAndroid Build Coastguard Worker // 72*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.doitUpFloat(int) loop_optimization (after) 73*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 74*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none doitUpFloat(int n)75*795d594fSAndroid Build Coastguard Worker static float doitUpFloat(int n) { 76*795d594fSAndroid Build Coastguard Worker // FP arithmetic is not sufficiently precise. 77*795d594fSAndroid Build Coastguard Worker // The loop remains. 78*795d594fSAndroid Build Coastguard Worker float lF = 1.0f; 79*795d594fSAndroid Build Coastguard Worker for (int i1 = 0; i1 < n; i1++) { 80*795d594fSAndroid Build Coastguard Worker lF = (1486662021.0f - lF); 81*795d594fSAndroid Build Coastguard Worker } 82*795d594fSAndroid Build Coastguard Worker return lF; 83*795d594fSAndroid Build Coastguard Worker } 84*795d594fSAndroid Build Coastguard Worker 85*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.doitDownFloat(int) loop_optimization (before) 86*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 87*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 88*795d594fSAndroid Build Coastguard Worker // 89*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.doitDownFloat(int) loop_optimization (after) 90*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 91*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none doitDownFloat(int n)92*795d594fSAndroid Build Coastguard Worker static float doitDownFloat(int n) { 93*795d594fSAndroid Build Coastguard Worker // FP arithmetic is not sufficiently precise. 94*795d594fSAndroid Build Coastguard Worker // The loop remains. 95*795d594fSAndroid Build Coastguard Worker float lF = 1.0f; 96*795d594fSAndroid Build Coastguard Worker for (int i1 = n - 1; i1 >= 0; i1--) { 97*795d594fSAndroid Build Coastguard Worker lF = (1486662021.0f - lF); 98*795d594fSAndroid Build Coastguard Worker } 99*795d594fSAndroid Build Coastguard Worker return lF; 100*795d594fSAndroid Build Coastguard Worker } 101*795d594fSAndroid Build Coastguard Worker 102*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.doitUpFloatAlt(int) loop_optimization (before) 103*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 104*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 105*795d594fSAndroid Build Coastguard Worker // 106*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.doitUpFloatAlt(int) loop_optimization (after) 107*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi doitUpFloatAlt(int n)108*795d594fSAndroid Build Coastguard Worker static float doitUpFloatAlt(int n) { 109*795d594fSAndroid Build Coastguard Worker // Complete loop is replaced by last-value 110*795d594fSAndroid Build Coastguard Worker // since the values are now precise. 111*795d594fSAndroid Build Coastguard Worker float lF = 1.0f; 112*795d594fSAndroid Build Coastguard Worker float l2 = 1486662020.0f; 113*795d594fSAndroid Build Coastguard Worker for (int i1 = 0; i1 < n; i1++) { 114*795d594fSAndroid Build Coastguard Worker float old = lF; 115*795d594fSAndroid Build Coastguard Worker lF = l2; 116*795d594fSAndroid Build Coastguard Worker l2 = old; 117*795d594fSAndroid Build Coastguard Worker } 118*795d594fSAndroid Build Coastguard Worker return lF; 119*795d594fSAndroid Build Coastguard Worker } 120*795d594fSAndroid Build Coastguard Worker 121*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.doitDownFloatAlt(int) loop_optimization (before) 122*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 123*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 124*795d594fSAndroid Build Coastguard Worker // 125*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.doitDownFloatAlt(int) loop_optimization (after) 126*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi doitDownFloatAlt(int n)127*795d594fSAndroid Build Coastguard Worker static float doitDownFloatAlt(int n) { 128*795d594fSAndroid Build Coastguard Worker // Complete loop is replaced by last-value 129*795d594fSAndroid Build Coastguard Worker // since the values are now precise. 130*795d594fSAndroid Build Coastguard Worker float lF = 1.0f; 131*795d594fSAndroid Build Coastguard Worker float l2 = 1486662020.0f; 132*795d594fSAndroid Build Coastguard Worker for (int i1 = n - 1; i1 >= 0; i1--) { 133*795d594fSAndroid Build Coastguard Worker float old = lF; 134*795d594fSAndroid Build Coastguard Worker lF = l2; 135*795d594fSAndroid Build Coastguard Worker l2 = old; 136*795d594fSAndroid Build Coastguard Worker } 137*795d594fSAndroid Build Coastguard Worker return lF; 138*795d594fSAndroid Build Coastguard Worker } 139*795d594fSAndroid Build Coastguard Worker 140*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.doitDownFloatAlt2(int) loop_optimization (before) 141*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 142*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none 143*795d594fSAndroid Build Coastguard Worker // 144*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.doitDownFloatAlt2(int) loop_optimization (after) 145*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Phi doitDownFloatAlt2(int n)146*795d594fSAndroid Build Coastguard Worker static float doitDownFloatAlt2(int n) { 147*795d594fSAndroid Build Coastguard Worker // Complete loop is replaced by last-value 148*795d594fSAndroid Build Coastguard Worker // since the values are now precise. 149*795d594fSAndroid Build Coastguard Worker float lF = 1.0f; 150*795d594fSAndroid Build Coastguard Worker float l2 = 1486662020.0f; 151*795d594fSAndroid Build Coastguard Worker for (int i1 = n; i1 > 0; i1--) { 152*795d594fSAndroid Build Coastguard Worker float old = lF; 153*795d594fSAndroid Build Coastguard Worker lF = l2; 154*795d594fSAndroid Build Coastguard Worker l2 = old; 155*795d594fSAndroid Build Coastguard Worker } 156*795d594fSAndroid Build Coastguard Worker return lF; 157*795d594fSAndroid Build Coastguard Worker } 158*795d594fSAndroid Build Coastguard Worker 159*795d594fSAndroid Build Coastguard Worker // Main driver. main(String[] args)160*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 161*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 162*795d594fSAndroid Build Coastguard Worker int ei = (i & 1) == 0 ? 1 : 1486662020; 163*795d594fSAndroid Build Coastguard Worker int ci = doitUpInt(i); 164*795d594fSAndroid Build Coastguard Worker expectEquals(ei, ci); 165*795d594fSAndroid Build Coastguard Worker } 166*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 167*795d594fSAndroid Build Coastguard Worker int ei = (i & 1) == 0 ? 1 : 1486662020; 168*795d594fSAndroid Build Coastguard Worker int ci = doitDownInt(i); 169*795d594fSAndroid Build Coastguard Worker expectEquals(ei, ci); 170*795d594fSAndroid Build Coastguard Worker } 171*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 172*795d594fSAndroid Build Coastguard Worker int ei = (i & 1) == 0 ? 1 : 1486662020; 173*795d594fSAndroid Build Coastguard Worker int ci = doitDownInt2(i); 174*795d594fSAndroid Build Coastguard Worker expectEquals(ei, ci); 175*795d594fSAndroid Build Coastguard Worker } 176*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 177*795d594fSAndroid Build Coastguard Worker float ef = i == 0 ? 1.0f : ((i & 1) == 0 ? 0.0f : 1486662021.0f); 178*795d594fSAndroid Build Coastguard Worker float cf = doitUpFloat(i); 179*795d594fSAndroid Build Coastguard Worker expectEquals(ef, cf); 180*795d594fSAndroid Build Coastguard Worker } 181*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 182*795d594fSAndroid Build Coastguard Worker float ef = i == 0 ? 1.0f : ((i & 1) == 0 ? 0.0f : 1486662021.0f); 183*795d594fSAndroid Build Coastguard Worker float cf = doitDownFloat(i); 184*795d594fSAndroid Build Coastguard Worker expectEquals(ef, cf); 185*795d594fSAndroid Build Coastguard Worker } 186*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 187*795d594fSAndroid Build Coastguard Worker float ef = (i & 1) == 0 ? 1.0f : 1486662020.0f; 188*795d594fSAndroid Build Coastguard Worker float cf = doitUpFloatAlt(i); 189*795d594fSAndroid Build Coastguard Worker expectEquals(ef, cf); 190*795d594fSAndroid Build Coastguard Worker } 191*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 192*795d594fSAndroid Build Coastguard Worker float ef = (i & 1) == 0 ? 1.0f : 1486662020.0f; 193*795d594fSAndroid Build Coastguard Worker float cf = doitDownFloatAlt(i); 194*795d594fSAndroid Build Coastguard Worker expectEquals(ef, cf); 195*795d594fSAndroid Build Coastguard Worker } 196*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 197*795d594fSAndroid Build Coastguard Worker float ef = (i & 1) == 0 ? 1.0f : 1486662020.0f; 198*795d594fSAndroid Build Coastguard Worker float cf = doitDownFloatAlt2(i); 199*795d594fSAndroid Build Coastguard Worker expectEquals(ef, cf); 200*795d594fSAndroid Build Coastguard Worker } 201*795d594fSAndroid Build Coastguard Worker System.out.println("passed"); 202*795d594fSAndroid Build Coastguard Worker } 203*795d594fSAndroid Build Coastguard Worker expectEquals(int expected, int result)204*795d594fSAndroid Build Coastguard Worker private static void expectEquals(int expected, int result) { 205*795d594fSAndroid Build Coastguard Worker if (expected != result) { 206*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + result); 207*795d594fSAndroid Build Coastguard Worker } 208*795d594fSAndroid Build Coastguard Worker } 209*795d594fSAndroid Build Coastguard Worker expectEquals(float expected, float result)210*795d594fSAndroid Build Coastguard Worker private static void expectEquals(float expected, float result) { 211*795d594fSAndroid Build Coastguard Worker if (expected != result) { 212*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + result); 213*795d594fSAndroid Build Coastguard Worker } 214*795d594fSAndroid Build Coastguard Worker } 215*795d594fSAndroid Build Coastguard Worker } 216*795d594fSAndroid Build Coastguard Worker 217*795d594fSAndroid Build Coastguard Worker 218