aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Stubbs <ams@codesourcery.com>2020-02-10 13:23:29 +0000
committerAndrew Stubbs <ams@codesourcery.com>2020-07-03 11:00:28 +0100
commitbf628a97efaf11204ab02527b30ca71d7759ca37 (patch)
tree5aab130b83bd083d48fa8b26aea9f6073e978556
parent9e5508c2d006f2d4f8670e6c3fed770ac1c85e64 (diff)
downloadgcc-bf628a97efaf11204ab02527b30ca71d7759ca37.zip
gcc-bf628a97efaf11204ab02527b30ca71d7759ca37.tar.gz
gcc-bf628a97efaf11204ab02527b30ca71d7759ca37.tar.bz2
amdgcn: Add fold_left_plus vector reductions
These aren't real in-order instructions, because the ISA can't do that quickly, but a means to allow regular out-of-order reductions when that's good enough, but the middle-end doesn't know so. gcc/ * config/gcn/gcn-valu.md (fold_left_plus_<mode>): New.
-rw-r--r--gcc/config/gcn/gcn-valu.md20
1 files changed, 20 insertions, 0 deletions
diff --git a/gcc/config/gcn/gcn-valu.md b/gcc/config/gcn/gcn-valu.md
index 6d7feca..26559ff 100644
--- a/gcc/config/gcn/gcn-valu.md
+++ b/gcc/config/gcn/gcn-valu.md
@@ -3076,6 +3076,26 @@
DONE;
})
+;; Warning: This "-ffast-math" implementation converts in-order reductions
+;; into associative reductions. It's also used where OpenMP or
+;; OpenACC paralellization has already broken the in-order semantics.
+(define_expand "fold_left_plus_<mode>"
+ [(match_operand:<SCALAR_MODE> 0 "register_operand")
+ (match_operand:<SCALAR_MODE> 1 "gcn_alu_operand")
+ (match_operand:V_FP 2 "gcn_alu_operand")]
+ "can_create_pseudo_p ()
+ && (flag_openacc || flag_openmp
+ || flag_associative_math)"
+ {
+ rtx dest = operands[0];
+ rtx scalar = operands[1];
+ rtx vector = operands[2];
+ rtx tmp = gen_reg_rtx (<SCALAR_MODE>mode);
+
+ emit_insn (gen_reduc_plus_scal_<mode> (tmp, vector));
+ emit_insn (gen_add<scalar_mode>3 (dest, scalar, tmp));
+ DONE;
+ })
(define_insn "*<reduc_op>_dpp_shr_<mode>"
[(set (match_operand:V_1REG 0 "register_operand" "=v")