From: Maciej W. Rozycki Date: Wed, 14 Jun 2017 23:26:40 +0000 (+0000) Subject: MIPS16/GCC: Emit bounds checking as RTL in `casesi' X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3466430f382b6adc2363721056b9abde3acd790a;p=gcc.git MIPS16/GCC: Emit bounds checking as RTL in `casesi' gcc/ * config/mips/mips.md (MIPS16_T_REGNUM): Remove constant. (casesi): Emit bounds checking as RTL. (casesi_internal_mips16_): Remove bounds checking. gcc/testsuite/ * gcc.target/mips/data-sym-jump.c: Adjust for whitespace changes. * gcc.target/mips/pr51513-1.c: New test. * gcc.target/mips/pr51513-2.c: New test. From-SVN: r249207 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 09435d094dd..2d5110c8d86 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-06-14 Maciej W. Rozycki + + * config/mips/mips.md (MIPS16_T_REGNUM): Remove constant. + (casesi): Emit bounds checking as RTL. + (casesi_internal_mips16_): Remove bounds checking. + 2017-06-14 Max Filippov * config/xtensa/xtensa.c (xtensa_option_override): Append diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 28e0a444ba9..971af6f8e09 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -162,7 +162,6 @@ [(TLS_GET_TP_REGNUM 3) (GET_FCSR_REGNUM 2) (SET_FCSR_REGNUM 4) - (MIPS16_T_REGNUM 24) (PIC_FUNCTION_ADDR_REGNUM 25) (RETURN_ADDR_REGNUM 31) (CPRESTORE_SLOT_REGNUM 76) @@ -6389,68 +6388,57 @@ if (!arith_operand (operands[0], SImode)) operands[0] = force_reg (SImode, operands[0]); - operands[2] = GEN_INT (INTVAL (operands[2]) + 1); - + emit_cmp_and_jump_insns (operands[0], operands[2], GTU, + NULL_RTX, SImode, 1, operands[4]); emit_jump_insn (PMODE_INSN (gen_casesi_internal_mips16, - (operands[0], operands[2], - operands[3], operands[4]))); - + (operands[0], operands[3]))); DONE; }) (define_insn "casesi_internal_mips16_" [(set (pc) - (if_then_else - (ltu (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "arith_operand" "dI")) - (unspec:P - [(match_dup 0) - (label_ref (match_operand 2 "" ""))] - UNSPEC_CASESI_DISPATCH) - (label_ref (match_operand 3 "" "")))) - (clobber (match_scratch:P 4 "=d")) - (clobber (match_scratch:P 5 "=d")) - (clobber (reg:SI MIPS16_T_REGNUM))] + (unspec:P [(match_operand:SI 0 "register_operand" "d") + (label_ref (match_operand 1 "" ""))] + UNSPEC_CASESI_DISPATCH)) + (clobber (match_scratch:P 2 "=d")) + (clobber (match_scratch:P 3 "=d"))] "TARGET_MIPS16_SHORT_JUMP_TABLES" { - rtx diff_vec = PATTERN (NEXT_INSN (as_a (operands[2]))); + rtx diff_vec = PATTERN (NEXT_INSN (as_a (operands[1]))); gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC); - - output_asm_insn ("sltu\t%0, %1", operands); - output_asm_insn ("bteqz\t%3", operands); - + switch (GET_MODE (diff_vec)) { case HImode: - output_asm_insn ("sll\t%5, %0, 1", operands); - output_asm_insn ("la\t%4, %2", operands); - output_asm_insn ("addu\t%5, %4, %5", operands); - output_asm_insn ("lh\t%5, 0(%5)", operands); + output_asm_insn ("sll\t%3,%0,1", operands); + output_asm_insn ("la\t%2,%1", operands); + output_asm_insn ("addu\t%3,%2,%3", operands); + output_asm_insn ("lh\t%3,0(%3)", operands); break; case SImode: - output_asm_insn ("sll\t%5, %0, 2", operands); - output_asm_insn ("la\t%4, %2", operands); - output_asm_insn ("addu\t%5, %4, %5", operands); - output_asm_insn ("lw\t%5, 0(%5)", operands); + output_asm_insn ("sll\t%3,%0,2", operands); + output_asm_insn ("la\t%2,%1", operands); + output_asm_insn ("addu\t%3,%2,%3", operands); + output_asm_insn ("lw\t%3,0(%3)", operands); break; default: gcc_unreachable (); } - output_asm_insn ("addu\t%4, %4, %5", operands); + output_asm_insn ("addu\t%2,%2,%3", operands); if (GENERATE_MIPS16E) - return "jrc\t%4"; + return "jrc\t%2"; else - return "jr\t%4"; + return "jr\t%2"; } [(set (attr "insn_count") (if_then_else (match_test "GENERATE_MIPS16E") - (const_string "10") - (const_string "11")))]) + (const_string "6") + (const_string "7")))]) ;; For TARGET_USE_GOT, we save the gp in the jmp_buf as well. ;; While it is possible to either pull it off the stack (in the diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a0c522ea680..dc82af01557 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2017-06-14 Maciej W. Rozycki + + * gcc.target/mips/data-sym-jump.c: Adjust for whitespace changes. + * gcc.target/mips/pr51513-1.c: New test. + * gcc.target/mips/pr51513-2.c: New test. + 2017-06-14 Richard Biener PR tree-optimization/81083 diff --git a/gcc/testsuite/gcc.target/mips/data-sym-jump.c b/gcc/testsuite/gcc.target/mips/data-sym-jump.c index c3ba2944cdc..ae48c0b4b5c 100644 --- a/gcc/testsuite/gcc.target/mips/data-sym-jump.c +++ b/gcc/testsuite/gcc.target/mips/data-sym-jump.c @@ -25,7 +25,7 @@ frob (int i) /* Expect assembly like: - la $2, $L4 + la $2,$L4 # Anything goes here. .type __jump_frob_4, @object # Symbol # must match label. __jump_frob_4: # The symbol must match. @@ -47,4 +47,4 @@ __jend_frob_4: # The symbol must match. that is `__jump_*'/`__jend_*' symbols inserted around a jump table. */ -/* { dg-final { scan-assembler "\tla\t\\\$\[0-9\]+, (.L(\[0-9\]+))\n.*\t\\.type\t(__jump_frob_\\2), @object\n\\3:\n\\1:\n(?:\t\\.(?:half|word)\t.L\[0-9\]+-\\1\n)\{11\}\t\\.type\t(__jend_frob_\\2), @function\n\\4:\n\t\\.insn\n" } } */ +/* { dg-final { scan-assembler "\tla\t\\\$\[0-9\]+,(.L(\[0-9\]+))\n.*\t\\.type\t(__jump_frob_\\2), @object\n\\3:\n\\1:\n(?:\t\\.(?:half|word)\t.L\[0-9\]+-\\1\n)\{11\}\t\\.type\t(__jend_frob_\\2), @function\n\\4:\n\t\\.insn\n" } } */ diff --git a/gcc/testsuite/gcc.target/mips/pr51513-1.c b/gcc/testsuite/gcc.target/mips/pr51513-1.c new file mode 100644 index 00000000000..b5e0d69fa29 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/pr51513-1.c @@ -0,0 +1,48 @@ +/* { dg-do compile } */ +/* { dg-options "-mips16 -mcode-readable=yes" } */ + +/* PR tree-optimization/51513 verification variant for MIPS16, #1. */ + +int __attribute__ ((weak)) +frob (int i) +{ + switch (i) + { + case -5: + return -2; + case -3: + return -1; + case 0: + return 0; + case 3: + return 1; + case 5: + break; + default: + __builtin_unreachable (); + } + return i; +} + +/* Without the fix for PR tree-optimization/51513 truncated code + would be emitted for `frob', like: + + .text + .align 2 + .weak frob + .set mips16 + .set nomicromips + .ent frob + .type frob, @function +frob: + .frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0 + .mask 0x00000000,0 + .fmask 0x00000000,0 + addiu $2,$4,5 + .end frob + .size frob, .-frob + + meaning `frob' will have no chance to return, let alone produce + the result expected. */ + +/* { dg-final { scan-assembler "\tjrc?\t\\\$31\n" } } */ diff --git a/gcc/testsuite/gcc.target/mips/pr51513-2.c b/gcc/testsuite/gcc.target/mips/pr51513-2.c new file mode 100644 index 00000000000..b921904fdff --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/pr51513-2.c @@ -0,0 +1,56 @@ +/* { dg-do run } */ +/* { dg-options "-mips16 -mcode-readable=yes" } */ + +/* PR tree-optimization/51513 verification variant for MIPS16, #2. */ + +int __attribute__ ((weak)) +frob (int i) +{ + switch (i) + { + case -5: + return -2; + case -3: + return -1; + case 0: + return 0; + case 3: + return 1; + case 5: + break; + default: + __builtin_unreachable (); + } + return i; +} + +int +main (void) +{ + return !(frob (-5) == -2 + & frob (-3) == -1 + & frob (0) == 0 + & frob (3) == 1 + & frob (5) == 5); +} + +/* Without the fix for PR tree-optimization/51513 truncated code + would be emitted for `frob', like: + + .text + .align 2 + .weak frob + .set mips16 + .set nomicromips + .ent frob + .type frob, @function +frob: + .frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0 + .mask 0x00000000,0 + .fmask 0x00000000,0 + addiu $2,$4,5 + .end frob + .size frob, .-frob + + meaning `frob' will have no chance to return, let alone produce + the result expected. */