x86: don't suppress errors when optimizing
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_binutils_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_binutils_check--master-arm |
success
|
Test passed
|
Commit Message
Blindly ignoring any mnemonic suffix can't be quite right: Bad suffix /
operand combinations still want flagging. Simply avoid optimizing in
such situations.
---
Introducing a new helper function right here, for it to be used in v2 of
"x86: a few more optimizations".
Comments
Jan Beulich <jbeulich@suse.com> writes:
> Blindly ignoring any mnemonic suffix can't be quite right: Bad suffix /
> operand combinations still want flagging. Simply avoid optimizing in
> such situations.
> ---
> Introducing a new helper function right here, for it to be used in v2 of
> "x86: a few more optimizations".
>
> --- a/gas/config/tc-i386.c
> +++ b/gas/config/tc-i386.c
> @@ -4573,6 +4573,20 @@ check_hle (void)
> }
> }
>
> +/* Helper for optimization (running ahead of process_suffix()), to make sure we
> + convert only well-formed insns. @OP is the sized operand to cross check
> + against (typically a register). Checking against a single operand typically
> + suffices, as match_template() has already honored CheckOperandSize. */
> +
> +static bool is_plausible_suffix (unsigned int op)
> +{
> + return !i.suffix
> + || (i.suffix == BYTE_MNEM_SUFFIX && i.types[op].bitfield.byte)
> + || (i.suffix == WORD_MNEM_SUFFIX && i.types[op].bitfield.word)
> + || (i.suffix == LONG_MNEM_SUFFIX && i.types[op].bitfield.dword)
> + || (i.suffix == QWORD_MNEM_SUFFIX && i.types[op].bitfield.qword);
> +}
> +
> /* Encode aligned vector move as unaligned vector move. */
>
> static void
> @@ -4758,6 +4772,7 @@ optimize_encoding (void)
> && i.reg_operands == 1
> && i.imm_operands == 1
> && !i.types[1].bitfield.byte
> + && is_plausible_suffix (1)
> && i.op[0].imms->X_op == O_constant
> && fits_in_imm7 (i.op[0].imms->X_add_number))
> {
> @@ -4768,7 +4783,7 @@ optimize_encoding (void)
> if (flag_code == CODE_64BIT || base_regnum < 4)
> {
> i.types[1].bitfield.byte = 1;
> - /* Ignore the suffix. */
> + /* Squash the suffix. */
> i.suffix = 0;
> /* Convert to byte registers. 8-bit registers are special,
> RegRex64 and non-RegRex64 each have 8 registers. */
> --- a/gas/testsuite/gas/i386/i386.exp
> +++ b/gas/testsuite/gas/i386/i386.exp
> @@ -615,6 +615,7 @@ if [gas_32_check] then {
> run_list_test "optimize-6a" "-I${srcdir}/$subdir -march=+noavx -al"
> run_dump_test "optimize-6b"
> run_list_test "optimize-7" "-I${srcdir}/$subdir -march=+noavx2 -al"
> + run_list_test "optimize-8" "-Os"
> run_dump_test "noopt"
> run_dump_test "lea-optimize"
> run_dump_test "lea16-optimize"
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/optimize-8.l
> @@ -0,0 +1,4 @@
> +.*: Assembler messages:
> +.*:5: Error: .* `%ecx' .* suffix
> +.*:6: Error: .* `%cx' .* suffix
> +#pass
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/optimize-8.s
> @@ -0,0 +1,6 @@
> +# Check bogus instructions are still rejected when optimitating
optimi(z|s)ing
> +
> + .text
> +_start:
> + testw $4, %ecx
> + testl $4, %cx
@@ -4573,6 +4573,20 @@ check_hle (void)
}
}
+/* Helper for optimization (running ahead of process_suffix()), to make sure we
+ convert only well-formed insns. @OP is the sized operand to cross check
+ against (typically a register). Checking against a single operand typically
+ suffices, as match_template() has already honored CheckOperandSize. */
+
+static bool is_plausible_suffix (unsigned int op)
+{
+ return !i.suffix
+ || (i.suffix == BYTE_MNEM_SUFFIX && i.types[op].bitfield.byte)
+ || (i.suffix == WORD_MNEM_SUFFIX && i.types[op].bitfield.word)
+ || (i.suffix == LONG_MNEM_SUFFIX && i.types[op].bitfield.dword)
+ || (i.suffix == QWORD_MNEM_SUFFIX && i.types[op].bitfield.qword);
+}
+
/* Encode aligned vector move as unaligned vector move. */
static void
@@ -4758,6 +4772,7 @@ optimize_encoding (void)
&& i.reg_operands == 1
&& i.imm_operands == 1
&& !i.types[1].bitfield.byte
+ && is_plausible_suffix (1)
&& i.op[0].imms->X_op == O_constant
&& fits_in_imm7 (i.op[0].imms->X_add_number))
{
@@ -4768,7 +4783,7 @@ optimize_encoding (void)
if (flag_code == CODE_64BIT || base_regnum < 4)
{
i.types[1].bitfield.byte = 1;
- /* Ignore the suffix. */
+ /* Squash the suffix. */
i.suffix = 0;
/* Convert to byte registers. 8-bit registers are special,
RegRex64 and non-RegRex64 each have 8 registers. */
@@ -615,6 +615,7 @@ if [gas_32_check] then {
run_list_test "optimize-6a" "-I${srcdir}/$subdir -march=+noavx -al"
run_dump_test "optimize-6b"
run_list_test "optimize-7" "-I${srcdir}/$subdir -march=+noavx2 -al"
+ run_list_test "optimize-8" "-Os"
run_dump_test "noopt"
run_dump_test "lea-optimize"
run_dump_test "lea16-optimize"
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*:5: Error: .* `%ecx' .* suffix
+.*:6: Error: .* `%cx' .* suffix
+#pass
@@ -0,0 +1,6 @@
+# Check bogus instructions are still rejected when optimitating
+
+ .text
+_start:
+ testw $4, %ecx
+ testl $4, %cx