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
|
@ -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>
|
2016-01-05 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
PR target/68991
|
PR target/68991
|
||||||
|
|
|
@ -19359,11 +19359,11 @@ ix86_expand_vector_logical_operator (enum rtx_code code, machine_mode mode,
|
||||||
{
|
{
|
||||||
op1 = operands[1];
|
op1 = operands[1];
|
||||||
op2 = SUBREG_REG (operands[2]);
|
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);
|
op2 = force_reg (GET_MODE (dst), op2);
|
||||||
}
|
}
|
||||||
op1 = SUBREG_REG (op1);
|
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);
|
op1 = force_reg (GET_MODE (dst), op1);
|
||||||
emit_insn (gen_rtx_SET (dst,
|
emit_insn (gen_rtx_SET (dst,
|
||||||
gen_rtx_fmt_ee (code, GET_MODE (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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!nonimmediate_operand (operands[1], mode))
|
if (!vector_operand (operands[1], mode))
|
||||||
operands[1] = force_reg (mode, operands[1]);
|
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]);
|
operands[2] = force_reg (mode, operands[2]);
|
||||||
ix86_fixup_binary_operands_no_copy (code, mode, operands);
|
ix86_fixup_binary_operands_no_copy (code, mode, operands);
|
||||||
emit_insn (gen_rtx_SET (operands[0],
|
emit_insn (gen_rtx_SET (operands[0],
|
||||||
|
|
|
@ -958,6 +958,11 @@
|
||||||
(ior (match_test "TARGET_AVX")
|
(ior (match_test "TARGET_AVX")
|
||||||
(match_test "MEM_ALIGN (op) >= GET_MODE_ALIGNMENT (mode)"))))
|
(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.
|
; Return true when OP is operand acceptable for standard SSE move.
|
||||||
(define_predicate "vector_move_operand"
|
(define_predicate "vector_move_operand"
|
||||||
(ior (match_operand 0 "nonimmediate_operand")
|
(ior (match_operand 0 "nonimmediate_operand")
|
||||||
|
@ -1598,9 +1603,9 @@
|
||||||
return val == ((low << 8) | low);
|
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"
|
(define_predicate "general_vector_operand"
|
||||||
(ior (match_operand 0 "nonimmediate_operand")
|
(ior (match_operand 0 "vector_operand")
|
||||||
(match_code "const_vector")))
|
(match_code "const_vector")))
|
||||||
|
|
||||||
;; Return true if OP is either -1 constant or stored in register.
|
;; 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_constraint" "round" "vm" "v")
|
||||||
(define_subst_attr "round_constraint2" "round" "m" "v")
|
(define_subst_attr "round_constraint2" "round" "m" "v")
|
||||||
(define_subst_attr "round_constraint3" "round" "rm" "r")
|
(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_prefix" "round" "vex" "evex")
|
||||||
(define_subst_attr "round_mode512bit_condition" "round" "1" "(<MODE>mode == V16SFmode
|
(define_subst_attr "round_mode512bit_condition" "round" "1" "(<MODE>mode == V16SFmode
|
||||||
|| <MODE>mode == V8DFmode
|
|| <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_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_constraint" "round_saeonly" "vm" "v")
|
||||||
(define_subst_attr "round_saeonly_constraint2" "round_saeonly" "m" "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
|
(define_subst_attr "round_saeonly_mode512bit_condition" "round_saeonly" "1" "(<MODE>mode == V16SFmode
|
||||||
|| <MODE>mode == V8DFmode
|
|| <MODE>mode == V8DFmode
|
||||||
|| <MODE>mode == V8DImode
|
|| <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>
|
2016-01-05 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
PR target/68991
|
PR target/68991
|
||||||
|
|
|
@ -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…
Reference in New Issue