rs6000: Generate rl*imi for memory some more
An rl<wd>imi instruction is often written like "(a << 8) | (b & 255)". If "b" now is a byte in memory, combine will combine the load with the masking (with 255 in the example), since that is a single instruction; and then the rl*imi isn't combined from the remaining pieces. This patch adds a splitter to make combine handle this case. * config/rs6000/rs6000.md (splitters for rldimi and rlwimi with the zero_extend argument from memory): New. From-SVN: r262929
This commit is contained in:
parent
315aa691f4
commit
268e16e89b
2 changed files with 47 additions and 1 deletions
|
@ -1,7 +1,12 @@
|
|||
2018-07-23 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
|
||||
* config/rs6000/rs6000.md (splitters for rldimi and rlwimi with the
|
||||
zero_extend argument from memory): New.
|
||||
|
||||
2018-07-22 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR bootstrap/86621
|
||||
* gcc/gimple-ssa-warn-alloca.c (alloca_call_type_by_arg): Avoid
|
||||
* gimple-ssa-warn-alloca.c (alloca_call_type_by_arg): Avoid
|
||||
diagnosing calls with unknown arguments unless -Walloca-larger-than
|
||||
is restricted to less than PTRDIFF_MAX bytes.
|
||||
|
||||
|
|
|
@ -4065,6 +4065,47 @@
|
|||
(set_attr "length" "8")])
|
||||
|
||||
|
||||
; Yet another case is an rldimi with the second value coming from memory.
|
||||
; The zero_extend that should become part of the rldimi is merged into the
|
||||
; load from memory instead. Split things properly again.
|
||||
(define_split
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand")
|
||||
(ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
|
||||
(match_operand:SI 2 "const_int_operand"))
|
||||
(zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
|
||||
"INTVAL (operands[2]) == <bits>"
|
||||
[(set (match_dup 4)
|
||||
(zero_extend:DI (match_dup 3)))
|
||||
(set (match_dup 0)
|
||||
(ior:DI (and:DI (match_dup 4)
|
||||
(match_dup 5))
|
||||
(ashift:DI (match_dup 1)
|
||||
(match_dup 2))))]
|
||||
{
|
||||
operands[4] = gen_reg_rtx (DImode);
|
||||
operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
|
||||
})
|
||||
|
||||
; rlwimi, too.
|
||||
(define_split
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand")
|
||||
(ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
|
||||
(match_operand:SI 2 "const_int_operand"))
|
||||
(zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
|
||||
"INTVAL (operands[2]) == <bits>"
|
||||
[(set (match_dup 4)
|
||||
(zero_extend:SI (match_dup 3)))
|
||||
(set (match_dup 0)
|
||||
(ior:SI (and:SI (match_dup 4)
|
||||
(match_dup 5))
|
||||
(ashift:SI (match_dup 1)
|
||||
(match_dup 2))))]
|
||||
{
|
||||
operands[4] = gen_reg_rtx (SImode);
|
||||
operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
|
||||
})
|
||||
|
||||
|
||||
;; Now the simple shifts.
|
||||
|
||||
(define_insn "rotl<mode>3"
|
||||
|
|
Loading…
Add table
Reference in a new issue