Use vector_operand on SSE with 16b memory operand
Add vector_operand, which is vector_memory_operand or register_operand, and use it, instead of nonimmediate_operand, in SSE patterns with 16-byte memory operand. gcc/ PR target/68991 * config/i386/i386.c (ix86_expand_vector_logical_operator): Replace nonimmediate_operand with vector_operand. * config/i386/predicates.md (vector_operand): New predicate. (general_vector_operand): Replace nonimmediate_operand with vector_operand. * config/i386/sse.md: Replace nonimmediate_operand with vector_operand and m constraint with Bm constraint on SSE patterns with 16-byte memory operand. * config/i386/subst.md (round_nimm_predicate): Replace nonimmediate_operand with vector_operand. (round_saeonly_nimm_predicate): Likewise. (round_saeonly_nimm_scalar_predicate): New. gcc/testsuite/ PR target/68991 * gcc.target/i386/pr68991.c: New test. From-SVN: r232088
This commit is contained in:
parent
3f50525df2
commit
acf93f1edc
7 changed files with 305 additions and 245 deletions
|
@ -1,3 +1,19 @@
|
|||
2016-01-05 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/68991
|
||||
* config/i386/i386.c (ix86_expand_vector_logical_operator):
|
||||
Replace nonimmediate_operand with vector_operand.
|
||||
* config/i386/predicates.md (vector_operand): New predicate.
|
||||
(general_vector_operand): Replace nonimmediate_operand with
|
||||
vector_operand.
|
||||
* config/i386/sse.md: Replace nonimmediate_operand with
|
||||
vector_operand and m constraint with Bm constraint on SSE
|
||||
patterns with 16-byte memory operand.
|
||||
* config/i386/subst.md (round_nimm_predicate): Replace
|
||||
nonimmediate_operand with vector_operand.
|
||||
(round_saeonly_nimm_predicate): Likewise.
|
||||
(round_saeonly_nimm_scalar_predicate): New.
|
||||
|
||||
2016-01-05 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/68991
|
||||
|
|
|
@ -19359,11 +19359,11 @@ ix86_expand_vector_logical_operator (enum rtx_code code, machine_mode mode,
|
|||
{
|
||||
op1 = operands[1];
|
||||
op2 = SUBREG_REG (operands[2]);
|
||||
if (!nonimmediate_operand (op2, GET_MODE (dst)))
|
||||
if (!vector_operand (op2, GET_MODE (dst)))
|
||||
op2 = force_reg (GET_MODE (dst), op2);
|
||||
}
|
||||
op1 = SUBREG_REG (op1);
|
||||
if (!nonimmediate_operand (op1, GET_MODE (dst)))
|
||||
if (!vector_operand (op1, GET_MODE (dst)))
|
||||
op1 = force_reg (GET_MODE (dst), op1);
|
||||
emit_insn (gen_rtx_SET (dst,
|
||||
gen_rtx_fmt_ee (code, GET_MODE (dst),
|
||||
|
@ -19374,9 +19374,9 @@ ix86_expand_vector_logical_operator (enum rtx_code code, machine_mode mode,
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!nonimmediate_operand (operands[1], mode))
|
||||
if (!vector_operand (operands[1], mode))
|
||||
operands[1] = force_reg (mode, operands[1]);
|
||||
if (!nonimmediate_operand (operands[2], mode))
|
||||
if (!vector_operand (operands[2], mode))
|
||||
operands[2] = force_reg (mode, operands[2]);
|
||||
ix86_fixup_binary_operands_no_copy (code, mode, operands);
|
||||
emit_insn (gen_rtx_SET (operands[0],
|
||||
|
|
|
@ -958,6 +958,11 @@
|
|||
(ior (match_test "TARGET_AVX")
|
||||
(match_test "MEM_ALIGN (op) >= GET_MODE_ALIGNMENT (mode)"))))
|
||||
|
||||
; Return true when OP is register_operand or vector_memory_operand.
|
||||
(define_predicate "vector_operand"
|
||||
(ior (match_operand 0 "register_operand")
|
||||
(match_operand 0 "vector_memory_operand")))
|
||||
|
||||
; Return true when OP is operand acceptable for standard SSE move.
|
||||
(define_predicate "vector_move_operand"
|
||||
(ior (match_operand 0 "nonimmediate_operand")
|
||||
|
@ -1598,9 +1603,9 @@
|
|||
return val == ((low << 8) | low);
|
||||
})
|
||||
|
||||
;; Return true if OP is nonimmediate_operand or CONST_VECTOR.
|
||||
;; Return true if OP is vector_operand or CONST_VECTOR.
|
||||
(define_predicate "general_vector_operand"
|
||||
(ior (match_operand 0 "nonimmediate_operand")
|
||||
(ior (match_operand 0 "vector_operand")
|
||||
(match_code "const_vector")))
|
||||
|
||||
;; Return true if OP is either -1 constant or stored in register.
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -123,7 +123,7 @@
|
|||
(define_subst_attr "round_constraint" "round" "vm" "v")
|
||||
(define_subst_attr "round_constraint2" "round" "m" "v")
|
||||
(define_subst_attr "round_constraint3" "round" "rm" "r")
|
||||
(define_subst_attr "round_nimm_predicate" "round" "nonimmediate_operand" "register_operand")
|
||||
(define_subst_attr "round_nimm_predicate" "round" "vector_operand" "register_operand")
|
||||
(define_subst_attr "round_prefix" "round" "vex" "evex")
|
||||
(define_subst_attr "round_mode512bit_condition" "round" "1" "(<MODE>mode == V16SFmode
|
||||
|| <MODE>mode == V8DFmode
|
||||
|
@ -162,7 +162,8 @@
|
|||
(define_subst_attr "round_saeonly_sd_mask_op5" "round_saeonly" "" "<round_saeonly_sd_mask_operand5>")
|
||||
(define_subst_attr "round_saeonly_constraint" "round_saeonly" "vm" "v")
|
||||
(define_subst_attr "round_saeonly_constraint2" "round_saeonly" "m" "v")
|
||||
(define_subst_attr "round_saeonly_nimm_predicate" "round_saeonly" "nonimmediate_operand" "register_operand")
|
||||
(define_subst_attr "round_saeonly_nimm_predicate" "round_saeonly" "vector_operand" "register_operand")
|
||||
(define_subst_attr "round_saeonly_nimm_scalar_predicate" "round_saeonly" "nonimmediate_operand" "register_operand")
|
||||
(define_subst_attr "round_saeonly_mode512bit_condition" "round_saeonly" "1" "(<MODE>mode == V16SFmode
|
||||
|| <MODE>mode == V8DFmode
|
||||
|| <MODE>mode == V8DImode
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2016-01-05 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/68991
|
||||
* gcc.target/i386/pr68991.c: New test.
|
||||
|
||||
2016-01-05 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/68991
|
||||
|
|
32
gcc/testsuite/gcc.target/i386/pr68991.c
Normal file
32
gcc/testsuite/gcc.target/i386/pr68991.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -msse2 -mfpmath=sse" } */
|
||||
|
||||
float
|
||||
foo (float a, float b, float c, float d)
|
||||
{
|
||||
float ac, bd, ad, bc, y;
|
||||
|
||||
ac = a * c;
|
||||
bd = b * d;
|
||||
ad = a * d;
|
||||
bc = b * c;
|
||||
|
||||
if (__builtin_expect (!__builtin_expect ((a) != (a), 0)
|
||||
& !__builtin_expect (!__builtin_expect (((a) - (a)) != ((a) - (a)), 0), 1), 0)
|
||||
|| __builtin_expect (!__builtin_expect ((b) != (b), 0)
|
||||
& !__builtin_expect (!__builtin_expect (((b) - (b)) != ((b) - (b)), 0), 1), 0))
|
||||
a = __builtin_copysignf (__builtin_expect (!__builtin_expect ((a) != (a), 0)
|
||||
& !__builtin_expect (!__builtin_expect (((a) - (a)) != ((a) - (a)), 0), 1), 0) ? 1 : 0, a);
|
||||
|
||||
c = __builtin_copysignf (__builtin_expect (!__builtin_expect ((c) != (c), 0) & !__builtin_expect (!__builtin_expect (((c) - (c)) != ((c) - (c)), 0), 1), 0) ? 1 : 0, c);
|
||||
if ((__builtin_expect (!__builtin_expect ((ac) != (ac), 0)
|
||||
& !__builtin_expect (!__builtin_expect (((ac) - (ac)) != ((ac) - (ac)), 0), 1), 0)
|
||||
|| __builtin_expect (!__builtin_expect ((bd) != (bd), 0)
|
||||
& !__builtin_expect (!__builtin_expect (((bd) - (bd)) != ((bd) - (bd)), 0), 1), 0)
|
||||
|| __builtin_expect (!__builtin_expect ((bc) != (bc), 0) & !__builtin_expect (!__builtin_expect (((bc) - (bc)) != ((bc) - (bc)), 0), 1), 0)))
|
||||
d = __builtin_copysignf (0, d);
|
||||
|
||||
y = a * d + b * c;
|
||||
|
||||
return y;
|
||||
}
|
Loading…
Add table
Reference in a new issue