i386: Emit compares between high registers and memory
commit0df6d181230f0480547ed08b4e4354db68242724
authorUros Bizjak <ubizjak@gmail.com>
Wed, 19 Apr 2023 15:00:52 +0000 (19 17:00 +0200)
committerUros Bizjak <ubizjak@gmail.com>
Wed, 19 Apr 2023 15:04:10 +0000 (19 17:04 +0200)
tree2c1206c133e3bed786b37652e28e4263ca42f6ff
parenta30078d5d974c3b2c784c522a84fd12df74767dd
i386: Emit compares between high registers and memory

Following code:

typedef __SIZE_TYPE__ size_t;

struct S1s
{
  char pad1;
  char val;
  short pad2;
};

extern char ts[256];

_Bool foo (struct S1s a, size_t i)
{
  return (ts[i] > a.val);
}

compiles with -O2 to:

        movl    %edi, %eax
        movsbl  %ah, %edi
        cmpb    %dil, ts(%rsi)
        setg    %al
        ret

the compare could use high register %ah instead of %dil:

        movl    %edi, %eax
        cmpb    ts(%rsi), %ah
        setl    %al
        ret

Use any_extract code iterator to handle signed and unsigned extracts
from high register and introduce peephole2 patterns to propagate
norex memory opeerand into the compare insn.

gcc/ChangeLog:

PR target/78904
PR target/78952
* config/i386/i386.md (*cmpqi_ext<mode>_1_mem_rex64): New insn pattern.
(*cmpqi_ext<mode>_1): Use nonimmediate_operand predicate
for operand 0. Use any_extract code iterator.
(*cmpqi_ext<mode>_1 peephole2): New peephole2 pattern.
(*cmpqi_ext<mode>_2): Use any_extract code iterator.
(*cmpqi_ext<mode>_3_mem_rex64): New insn pattern.
(*cmpqi_ext<mode>_1): Use general_operand predicate
for operand 1. Use any_extract code iterator.
(*cmpqi_ext<mode>_3 peephole2): New peephole2 pattern.
(*cmpqi_ext<mode>_4): Use any_extract code iterator.

gcc/testsuite/ChangeLog:

PR target/78904
PR target/78952
* gcc.target/i386/pr78952-3.c: New test.
gcc/config/i386/i386.md
gcc/testsuite/gcc.target/i386/pr78952-3.c [new file with mode: 0644]