1 /*
   2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * @test
  26  * @bug 8210215
  27  * @summary Test that C2 correctly optimizes trichotomy expressions.
  28  * @library /test/lib
  29  * @run main/othervm -XX:-TieredCompilation -Xbatch
  30  *                   -XX:CompileCommand=dontinline,compiler.codegen.TestTrichotomyExpressions::test*
  31  *                   compiler.codegen.TestTrichotomyExpressions
  32  * @run main/othervm -XX:-TieredCompilation -Xcomp
  33  *                   -XX:CompileCommand=dontinline,compiler.codegen.TestTrichotomyExpressions::test*
  34  *                   compiler.codegen.TestTrichotomyExpressions
  35  */
  36 
  37 package compiler.codegen;
  38 
  39 import java.lang.annotation.ElementType;
  40 import java.lang.annotation.Retention;
  41 import java.lang.annotation.RetentionPolicy;
  42 import java.lang.annotation.Target;
  43 import java.lang.reflect.Method;
  44 
  45 import jdk.test.lib.Asserts;
  46 
  47 enum Operation { SMALLER, SMALLER_EQUAL, EQUAL, GREATER_EQUAL, GREATER, ALWAYS_FALSE }
  48 
  49 @Retention(RetentionPolicy.RUNTIME)
  50 @Target(ElementType.METHOD)
  51 @interface Test {
  52     Operation op();
  53 }
  54 
  55 public class TestTrichotomyExpressions {
  56 
  57     public static int compare1(int a, int b) {
  58         return (a < b) ? -1 : (a == b) ? 0 : 1; 
  59     }
  60 
  61     public static int compare2(int a, int b) {
  62         return (a < b) ? -1 : (a <= b) ? 0 : 1; 
  63     }
  64 
  65     public static int compare3(int a, int b) {
  66         return (a < b) ? -1 : (a > b) ? 1 : 0; 
  67     }
  68 
  69     public static int compare4(int a, int b) {
  70         return (a > b) ? 1 : (a < b) ? -1 : 0; 
  71     }
  72 
  73     public static int compare5(int a, int b) {
  74         return (a > b) ? 1 : (a == b) ? 0 : -1; 
  75     }
  76 
  77     public static int compare6(int a, int b) {
  78         return (a > b) ? 1 : (a >= b) ? 0 : -1; 
  79     }
  80 
  81     public static int compare7(int a, int b) {
  82         return (a == b) ? 0 : (a < b) ? -1 : 1; 
  83     }
  84 
  85     public static int compare8(int a, int b) {
  86         return (a == b) ? 0 : (a <= b) ? -1 : 1; 
  87     }
  88 
  89     public static int compare9(int a, int b) {
  90         return (a == b) ? 0 : (a > b) ? 1 : -1; 
  91     }
  92 
  93     public static int compare10(int a, int b) {
  94         return (a == b) ? 0 : (a >= b) ? 1 : -1; 
  95     }
  96 
  97     public static int compare11(int a, int b) {
  98         return (a >= b) ? 1 : (a > b) ? 2 : -1; 
  99     }
 100 
 101     public static int compare12(int a, int b) {
 102         return (a <= b) ? 1 : (a < b) ? 2 : -1; 
 103     }
 104 
 105     public static int compare13(int a, int b) {
 106         return (a == b) ? 1 : (a == b) ? 2 : -1; 
 107     }
 108 
 109     public static int compare14(int a, int b) {
 110         return (a != b) ? 1 : (a < b) ? 2 : -1; 
 111     }
 112 
 113 
 114 
 115     @Test(op = Operation.SMALLER)
 116     public static boolean testSmaller1(int a, int b) {
 117         return compare1(a, b) == -1;
 118     }
 119 
 120     @Test(op = Operation.SMALLER)
 121     public static boolean testSmaller2(int a, int b) {
 122         return compare1(a, b) < 0;
 123     }
 124 
 125     @Test(op = Operation.SMALLER)
 126     public static boolean testSmaller3(int a, int b) {
 127         return compare1(a, b) <= -1;
 128     }
 129 
 130     @Test(op = Operation.SMALLER)
 131     public static boolean testSmaller4(int a, int b) {
 132         return compare2(a, b) == -1;
 133     }
 134 
 135     @Test(op = Operation.SMALLER)
 136     public static boolean testSmaller5(int a, int b) {
 137         return compare2(a, b) < 0;
 138     }
 139 
 140     @Test(op = Operation.SMALLER)
 141     public static boolean testSmaller6(int a, int b) {
 142         return compare2(a, b) <= -1;
 143     }
 144 
 145     @Test(op = Operation.SMALLER)
 146     public static boolean testSmaller7(int a, int b) {
 147         return compare3(a, b) == -1;
 148     }
 149 
 150     @Test(op = Operation.SMALLER)
 151     public static boolean testSmaller8(int a, int b) {
 152         return compare3(a, b) < 0;
 153     }
 154 
 155     @Test(op = Operation.SMALLER)
 156     public static boolean testSmaller9(int a, int b) {
 157         return compare3(a, b) <= -1;
 158     }
 159 
 160     @Test(op = Operation.SMALLER)
 161     public static boolean testSmaller10(int a, int b) {
 162         return compare4(a, b) == -1;
 163     }
 164 
 165     @Test(op = Operation.SMALLER)
 166     public static boolean testSmaller11(int a, int b) {
 167         return compare4(a, b) < 0;
 168     }
 169 
 170     @Test(op = Operation.SMALLER)
 171     public static boolean testSmaller12(int a, int b) {
 172         return compare4(a, b) <= -1;
 173     }
 174 
 175     @Test(op = Operation.SMALLER)
 176     public static boolean testSmaller13(int a, int b) {
 177         return compare5(a, b) == -1;
 178     }
 179 
 180     @Test(op = Operation.SMALLER)
 181     public static boolean testSmaller14(int a, int b) {
 182         return compare5(a, b) < 0;
 183     }
 184 
 185     @Test(op = Operation.SMALLER)
 186     public static boolean testSmaller15(int a, int b) {
 187         return compare5(a, b) <= -1;
 188     }
 189 
 190     @Test(op = Operation.SMALLER)
 191     public static boolean testSmaller16(int a, int b) {
 192         return compare6(a, b) == -1;
 193     }
 194 
 195     @Test(op = Operation.SMALLER)
 196     public static boolean testSmaller17(int a, int b) {
 197         return compare6(a, b) < 0;
 198     }
 199 
 200     @Test(op = Operation.SMALLER)
 201     public static boolean testSmaller18(int a, int b) {
 202         return compare6(a, b) <= -1;
 203     }
 204 
 205     @Test(op = Operation.SMALLER)
 206     public static boolean testSmaller19(int a, int b) {
 207         return compare7(a, b) == -1;
 208     }
 209 
 210     @Test(op = Operation.SMALLER)
 211     public static boolean testSmaller20(int a, int b) {
 212         return compare7(a, b) < 0;
 213     }
 214 
 215     @Test(op = Operation.SMALLER)
 216     public static boolean testSmaller21(int a, int b) {
 217         return compare7(a, b) <= -1;
 218     }
 219 
 220     @Test(op = Operation.SMALLER)
 221     public static boolean testSmaller22(int a, int b) {
 222         return compare8(a, b) == -1;
 223     }
 224 
 225     @Test(op = Operation.SMALLER)
 226     public static boolean testSmaller23(int a, int b) {
 227         return compare8(a, b) < 0;
 228     }
 229 
 230     @Test(op = Operation.SMALLER)
 231     public static boolean testSmaller24(int a, int b) {
 232         return compare8(a, b) <= -1;
 233     }
 234 
 235     @Test(op = Operation.SMALLER)
 236     public static boolean testSmaller25(int a, int b) {
 237         return compare9(a, b) == -1;
 238     }
 239 
 240     @Test(op = Operation.SMALLER)
 241     public static boolean testSmaller26(int a, int b) {
 242         return compare9(a, b) < 0;
 243     }
 244 
 245     @Test(op = Operation.SMALLER)
 246     public static boolean testSmaller27(int a, int b) {
 247         return compare9(a, b) <= -1;
 248     }
 249 
 250     @Test(op = Operation.SMALLER)
 251     public static boolean testSmaller28(int a, int b) {
 252         return compare10(a, b) == -1;
 253     }
 254 
 255     @Test(op = Operation.SMALLER)
 256     public static boolean testSmaller29(int a, int b) {
 257         return compare10(a, b) < 0;
 258     }
 259 
 260     @Test(op = Operation.SMALLER)
 261     public static boolean testSmaller30(int a, int b) {
 262         return compare10(a, b) <= -1;
 263     }
 264 
 265 
 266     @Test(op = Operation.SMALLER_EQUAL)
 267     public static boolean testSmallerEqual1(int a, int b) {
 268         return compare1(a, b) <= 0;
 269     }
 270 
 271     @Test(op = Operation.SMALLER_EQUAL)
 272     public static boolean testSmallerEqual2(int a, int b) {
 273         return compare2(a, b) <= 0;
 274     }
 275 
 276     @Test(op = Operation.SMALLER_EQUAL)
 277     public static boolean testSmallerEqual3(int a, int b) {
 278         return compare3(a, b) <= 0;
 279     }
 280 
 281     @Test(op = Operation.SMALLER_EQUAL)
 282     public static boolean testSmallerEqual4(int a, int b) {
 283         return compare4(a, b) <= 0;
 284     }
 285 
 286     @Test(op = Operation.SMALLER_EQUAL)
 287     public static boolean testSmallerEqual5(int a, int b) {
 288         return compare5(a, b) <= 0;
 289     }
 290 
 291     @Test(op = Operation.SMALLER_EQUAL)
 292     public static boolean testSmallerEqual6(int a, int b) {
 293         return compare6(a, b) <= 0;
 294     }
 295 
 296     @Test(op = Operation.SMALLER_EQUAL)
 297     public static boolean testSmallerEqual7(int a, int b) {
 298         return compare7(a, b) <= 0;
 299     }
 300 
 301     @Test(op = Operation.SMALLER_EQUAL)
 302     public static boolean testSmallerEqual8(int a, int b) {
 303         return compare8(a, b) <= 0;
 304     }
 305 
 306     @Test(op = Operation.SMALLER_EQUAL)
 307     public static boolean testSmallerEqual9(int a, int b) {
 308         return compare9(a, b) <= 0;
 309     }
 310 
 311     @Test(op = Operation.SMALLER_EQUAL)
 312     public static boolean testSmallerEqual10(int a, int b) {
 313         return compare10(a, b) <= 0;
 314     }
 315 
 316 
 317     @Test(op = Operation.EQUAL)
 318     public static boolean testEqual1(int a, int b) {
 319         return compare1(a, b) == 0;
 320     }
 321 
 322     @Test(op = Operation.EQUAL)
 323     public static boolean testEqual2(int a, int b) {
 324         return compare2(a, b) == 0;
 325     }
 326 
 327     @Test(op = Operation.EQUAL)
 328     public static boolean testEqual3(int a, int b) {
 329         return compare3(a, b) == 0;
 330     }
 331 
 332     @Test(op = Operation.EQUAL)
 333     public static boolean testEqual4(int a, int b) {
 334         return compare4(a, b) == 0;
 335     }
 336 
 337     @Test(op = Operation.EQUAL)
 338     public static boolean testEqual5(int a, int b) {
 339         return compare5(a, b) == 0;
 340     }
 341 
 342     @Test(op = Operation.EQUAL)
 343     public static boolean testEqual6(int a, int b) {
 344         return compare6(a, b) == 0;
 345     }
 346 
 347     @Test(op = Operation.EQUAL)
 348     public static boolean testEqual7(int a, int b) {
 349         return compare7(a, b) == 0;
 350     }
 351 
 352     @Test(op = Operation.EQUAL)
 353     public static boolean testEqual8(int a, int b) {
 354         return compare8(a, b) == 0;
 355     }
 356 
 357     @Test(op = Operation.EQUAL)
 358     public static boolean testEqual9(int a, int b) {
 359         return compare9(a, b) == 0;
 360     }
 361 
 362     @Test(op = Operation.EQUAL)
 363     public static boolean testEqual10(int a, int b) {
 364         return compare10(a, b) == 0;
 365     }
 366 
 367 
 368     @Test(op = Operation.GREATER_EQUAL)
 369     public static boolean testGreaterEqual1(int a, int b) {
 370         return compare1(a, b) >= 0;
 371     }
 372 
 373     @Test(op = Operation.GREATER_EQUAL)
 374     public static boolean testGreaterEqual2(int a, int b) {
 375         return compare2(a, b) >= 0;
 376     }
 377 
 378     @Test(op = Operation.GREATER_EQUAL)
 379     public static boolean testGreaterEqual3(int a, int b) {
 380         return compare3(a, b) >= 0;
 381     }
 382 
 383     @Test(op = Operation.GREATER_EQUAL)
 384     public static boolean testGreaterEqual4(int a, int b) {
 385         return compare4(a, b) >= 0;
 386     }
 387 
 388     @Test(op = Operation.GREATER_EQUAL)
 389     public static boolean testGreaterEqual5(int a, int b) {
 390         return compare5(a, b) >= 0;
 391     }
 392 
 393     @Test(op = Operation.GREATER_EQUAL)
 394     public static boolean testGreaterEqual6(int a, int b) {
 395         return compare6(a, b) >= 0;
 396     }
 397 
 398     @Test(op = Operation.GREATER_EQUAL)
 399     public static boolean testGreaterEqual7(int a, int b) {
 400         return compare7(a, b) >= 0;
 401     }
 402 
 403     @Test(op = Operation.GREATER_EQUAL)
 404     public static boolean testGreaterEqual8(int a, int b) {
 405         return compare8(a, b) >= 0;
 406     }
 407 
 408     @Test(op = Operation.GREATER_EQUAL)
 409     public static boolean testGreaterEqual9(int a, int b) {
 410         return compare9(a, b) >= 0;
 411     }
 412 
 413     @Test(op = Operation.GREATER_EQUAL)
 414     public static boolean testGreaterEqual10(int a, int b) {
 415         return compare10(a, b) >= 0;
 416     }
 417 
 418 
 419     @Test(op = Operation.GREATER)
 420     public static boolean testGreater1(int a, int b) {
 421         return compare1(a, b) == 1;
 422     }
 423 
 424     @Test(op = Operation.GREATER)
 425     public static boolean testGreater2(int a, int b) {
 426         return compare1(a, b) > 0;
 427     }
 428 
 429     @Test(op = Operation.GREATER)
 430     public static boolean testGreater3(int a, int b) {
 431         return compare1(a, b) >= 1;
 432     }
 433 
 434     @Test(op = Operation.GREATER)
 435     public static boolean testGreater4(int a, int b) {
 436         return compare2(a, b) == 1;
 437     }
 438 
 439     @Test(op = Operation.GREATER)
 440     public static boolean testGreater5(int a, int b) {
 441         return compare2(a, b) > 0;
 442     }
 443 
 444     @Test(op = Operation.GREATER)
 445     public static boolean testGreater6(int a, int b) {
 446         return compare2(a, b) >= 1;
 447     }
 448 
 449     @Test(op = Operation.GREATER)
 450     public static boolean testGreater7(int a, int b) {
 451         return compare3(a, b) == 1;
 452     }
 453 
 454     @Test(op = Operation.GREATER)
 455     public static boolean testGreater8(int a, int b) {
 456         return compare3(a, b) > 0;
 457     }
 458 
 459     @Test(op = Operation.GREATER)
 460     public static boolean testGreater9(int a, int b) {
 461         return compare3(a, b) >= 1;
 462     }
 463 
 464     @Test(op = Operation.GREATER)
 465     public static boolean testGreater10(int a, int b) {
 466         return compare4(a, b) == 1;
 467     }
 468 
 469     @Test(op = Operation.GREATER)
 470     public static boolean testGreater11(int a, int b) {
 471         return compare4(a, b) > 0;
 472     }
 473 
 474     @Test(op = Operation.GREATER)
 475     public static boolean testGreater12(int a, int b) {
 476         return compare4(a, b) >= 1;
 477     }
 478 
 479     @Test(op = Operation.GREATER)
 480     public static boolean testGreater13(int a, int b) {
 481         return compare5(a, b) == 1;
 482     }
 483 
 484     @Test(op = Operation.GREATER)
 485     public static boolean testGreater14(int a, int b) {
 486         return compare5(a, b) > 0;
 487     }
 488 
 489     @Test(op = Operation.GREATER)
 490     public static boolean testGreater15(int a, int b) {
 491         return compare5(a, b) >= 1;
 492     }
 493 
 494     @Test(op = Operation.GREATER)
 495     public static boolean testGreater16(int a, int b) {
 496         return compare6(a, b) == 1;
 497     }
 498 
 499     @Test(op = Operation.GREATER)
 500     public static boolean testGreater17(int a, int b) {
 501         return compare6(a, b) > 0;
 502     }
 503 
 504     @Test(op = Operation.GREATER)
 505     public static boolean testGreater18(int a, int b) {
 506         return compare6(a, b) >= 1;
 507     }
 508 
 509     @Test(op = Operation.GREATER)
 510     public static boolean testGreater19(int a, int b) {
 511         return compare7(a, b) == 1;
 512     }
 513 
 514     @Test(op = Operation.GREATER)
 515     public static boolean testGreater20(int a, int b) {
 516         return compare7(a, b) > 0;
 517     }
 518 
 519     @Test(op = Operation.GREATER)
 520     public static boolean testGreater21(int a, int b) {
 521         return compare7(a, b) >= 1;
 522     }
 523 
 524     @Test(op = Operation.GREATER)
 525     public static boolean testGreater22(int a, int b) {
 526         return compare8(a, b) == 1;
 527     }
 528 
 529     @Test(op = Operation.GREATER)
 530     public static boolean testGreater23(int a, int b) {
 531         return compare8(a, b) > 0;
 532     }
 533 
 534     @Test(op = Operation.GREATER)
 535     public static boolean testGreater24(int a, int b) {
 536         return compare8(a, b) >= 1;
 537     }
 538 
 539     @Test(op = Operation.GREATER)
 540     public static boolean testGreater25(int a, int b) {
 541         return compare9(a, b) == 1;
 542     }
 543 
 544     @Test(op = Operation.GREATER)
 545     public static boolean testGreater26(int a, int b) {
 546         return compare9(a, b) > 0;
 547     }
 548 
 549     @Test(op = Operation.GREATER)
 550     public static boolean testGreater27(int a, int b) {
 551         return compare9(a, b) >= 1;
 552     }
 553 
 554     @Test(op = Operation.GREATER)
 555     public static boolean testGreater28(int a, int b) {
 556         return compare10(a, b) == 1;
 557     }
 558 
 559     @Test(op = Operation.GREATER)
 560     public static boolean testGreater29(int a, int b) {
 561         return compare10(a, b) > 0;
 562     }
 563 
 564     @Test(op = Operation.GREATER)
 565     public static boolean testGreater30(int a, int b) {
 566         return compare10(a, b) >= 1;
 567     }
 568 
 569 
 570     @Test(op = Operation.ALWAYS_FALSE)
 571     public static boolean testAlwaysFalse1(int a, int b) {
 572         return compare11(a, b) == 2;
 573     }
 574 
 575     @Test(op = Operation.ALWAYS_FALSE)
 576     public static boolean testAlwaysFalse2(int a, int b) {
 577         return compare11(a, b) > 1;
 578     }
 579 
 580     @Test(op = Operation.ALWAYS_FALSE)
 581     public static boolean testAlwaysFalse3(int a, int b) {
 582         return compare11(a, b) >= 2;
 583     }
 584 
 585     @Test(op = Operation.ALWAYS_FALSE)
 586     public static boolean testAlwaysFalse4(int a, int b) {
 587         return compare12(a, b) == 2;
 588     }
 589 
 590     @Test(op = Operation.ALWAYS_FALSE)
 591     public static boolean testAlwaysFalse5(int a, int b) {
 592         return compare12(a, b) > 1;
 593     }
 594 
 595     @Test(op = Operation.ALWAYS_FALSE)
 596     public static boolean testAlwaysFalse6(int a, int b) {
 597         return compare12(a, b) >= 2;
 598     }
 599 
 600     @Test(op = Operation.ALWAYS_FALSE)
 601     public static boolean testAlwaysFalse7(int a, int b) {
 602         return compare13(a, b) == 2;
 603     }
 604 
 605     @Test(op = Operation.ALWAYS_FALSE)
 606     public static boolean testAlwaysFalse8(int a, int b) {
 607         return compare13(a, b) > 1;
 608     }
 609 
 610     @Test(op = Operation.ALWAYS_FALSE)
 611     public static boolean testAlwaysFalse9(int a, int b) {
 612         return compare13(a, b) >= 2;
 613     }
 614 
 615     @Test(op = Operation.ALWAYS_FALSE)
 616     public static boolean testAlwaysFalse10(int a, int b) {
 617         return compare14(a, b) == 2;
 618     }
 619 
 620     @Test(op = Operation.ALWAYS_FALSE)
 621     public static boolean testAlwaysFalse11(int a, int b) {
 622         return compare14(a, b) > 1;
 623     }
 624 
 625     @Test(op = Operation.ALWAYS_FALSE)
 626     public static boolean testAlwaysFalse12(int a, int b) {
 627         return compare14(a, b) >= 2;
 628     }
 629 
 630     public static void main(String[] args) throws Exception {
 631         for (int i = 0; i < 20_000; ++i) {
 632             for (Method m : TestTrichotomyExpressions.class.getMethods()) {
 633                 if (m.isAnnotationPresent(Test.class)) {
 634                     Operation op = m.getAnnotation(Test.class).op();
 635                     boolean result = (boolean)m.invoke(null, 0, 0);
 636                     Asserts.assertEquals(result, (op == Operation.EQUAL || op == Operation.SMALLER_EQUAL || op == Operation.GREATER_EQUAL) ? true : false);
 637                     result = (boolean)m.invoke(null, 0, 1);
 638                     Asserts.assertEquals(result, (op == Operation.SMALLER || op == Operation.SMALLER_EQUAL) ? true : false);
 639                     result = (boolean)m.invoke(null, 1, 0);
 640                     Asserts.assertEquals(result, (op == Operation.GREATER || op == Operation.GREATER_EQUAL) ? true : false);
 641                 }
 642             }
 643         }
 644     }
 645 }