/* Check that the div0s instruction is used for integer sign comparisons. Each test case is expected to emit at least one div0s insn. Problems when combining the div0s comparison result with surrounding logic usually show up as redundant tst insns. */ /* { dg-do compile } */ /* { dg-options "-O2" } */ /* { dg-final { scan-assembler-times "div0s" 42 } } */ /* { dg-final { scan-assembler-not "tst" } } */ /* { dg-final { scan-assembler-not "not\t" } } */ /* { dg-final { scan-assembler-not "nott" } } */ /* { dg-final { scan-assembler-times "negc" 10 { target { ! sh2a } } } } */ /* { dg-final { scan-assembler-times "movrt" 10 { target { sh2a } } } } */ typedef unsigned char bool; int other_func_a (int, int); int other_func_b (int, int); bool test_00 (int a, int b) { return (a ^ b) >= 0; } bool test_01 (int a, int b) { return (a ^ b) < 0; } int test_02 (int a, int b, int c, int d) { if ((a ^ b) < 0) return other_func_a (a, c); else return other_func_b (d, b); } int test_03 (int a, int b, int c, int d) { if ((a ^ b) >= 0) return other_func_a (a, c); else return other_func_b (d, b); } int test_04 (int a, int b) { return (a ^ b) >= 0 ? -20 : -40; } bool test_05 (int a, int b) { return (a ^ b) < 0; } int test_06 (int a, int b) { return (a ^ b) < 0 ? -20 : -40; } bool test_07 (int a, int b) { return (a < 0) == (b < 0); } int test_08 (int a, int b) { return (a < 0) == (b < 0) ? -20 : -40; } bool test_09 (int a, int b) { return (a < 0) != (b < 0); } int test_10 (int a, int b) { return (a < 0) != (b < 0) ? -20 : -40; } bool test_11 (int a, int b) { return (a >= 0) ^ (b < 0); } int test_12 (int a, int b) { return (a >= 0) ^ (b < 0) ? -20 : -40; } bool test_13 (int a, int b) { return !((a >= 0) ^ (b < 0)); } int test_14 (int a, int b) { return !((a >= 0) ^ (b < 0)) ? -20 : -40; } bool test_15 (int a, int b) { return (a & 0x80000000) == (b & 0x80000000); } int test_16 (int a, int b) { return (a & 0x80000000) == (b & 0x80000000) ? -20 : -40; } bool test_17 (int a, int b) { return (a & 0x80000000) != (b & 0x80000000); } int test_18 (int a, int b) { return (a & 0x80000000) != (b & 0x80000000) ? -20 : -40; } int test_19 (unsigned int a, unsigned int b) { return (a ^ b) >> 31; } int test_20 (unsigned int a, unsigned int b) { return (a >> 31) ^ (b >> 31); } int test_21 (int a, int b) { return ((a & 0x80000000) ^ (b & 0x80000000)) >> 31 ? -30 : -10; } int test_22 (int a, int b, int c, int d) { if ((a < 0) == (b < 0)) return other_func_a (a, b); else return other_func_b (c, d); } bool test_23 (int a, int b, int c, int d) { /* Should emit 2x div0s. */ return ((a < 0) == (b < 0)) | ((c < 0) == (d < 0)); } bool test_24 (int a, int b) { return a >= 0 != b >= 0; } bool test_25 (int a, int b) { return !(a < 0 != b < 0); } int test_26 (int a, int b, int c, int d) { return a >= 0 != b >= 0 ? c : d; } int test_27 (int a, int b) { return a >= 0 == b >= 0; } int test_28 (int a, int b, int c, int d) { return a >= 0 == b >= 0 ? c : d; } int test_29 (int a, int b) { return ((a >> 31) ^ (b >= 0)) & 1; } int test_30 (int a, int b) { return ((a >> 31) ^ (b >> 31)) & 1; } // ------------------------------------------------------- bool test_31 (int a, int b) { /* 2x exts.w, div0s */ return ((a & 0x8000) ^ (b & 0x8000)) != 0; } bool test_32 (int a, int b) { /* 2x exts.w, div0s */ return (a & 0x8000) != (b & 0x8000); } bool test_33 (int a, int b) { /* 2x add/shll, div0s */ return ((a & (1<<30)) ^ (b & (1<<30))) != 0; } bool test_34 (int a, int b) { /* 2x exts.b, div0s */ return (a & 0x80) != (b & 0x80); } bool test_35 (signed char a, signed char b) { /* 2x exts.b, div0s */ return (a < 0) != (b < 0); } bool test_36 (short a, short b) { /* 2x exts.w, div0s */ return (a < 0) != (b < 0); } int test_37 (short a, short b) { /* 2x exts.w, div0s */ return (a < 0) != (b < 0) ? 40 : -10; } bool test_38 (int a, int b) { /* 2x shll8, div0s */ return ((a & (1<<23)) ^ (b & (1<<23))) != 0; } bool test_39 (int a, int b) { /* 2x shll2, div0s */ return ((a & (1<<29)) ^ (b & (1<<29))) != 0; } bool test_40 (short a, short b) { /* 2x exts.w, div0s, negc */ return (a < 0) == (b < 0); }