From: Uros Bizjak Date: Tue, 22 Mar 2005 15:53:59 +0000 (+0100) Subject: re PR target/14981 (ICE in _mm_xor_pd for SSE2 with -O1) X-Git-Tag: releases/gcc-3.4.4~132 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ae71cc4ea49f063cefcaa43dc9d655dc74388ca1;p=thirdparty%2Fgcc.git re PR target/14981 (ICE in _mm_xor_pd for SSE2 with -O1) PR target/14981 Backport from mainline 2004-02-18 Jan Hubicka * simplify-rtx.c (simplify_unary_operation): Deal with logicals on floats. (simplify_binary_operation): Deal with logicals on floats. * i386.md (SSE fabs splitters): Emit new patterns. (SSE cmov splitters): Likewise. (sse_andv4sf3, sse_nandv4sf3, sse_iorv4sf3, sse_xorv4sf3 (sse_andv2df3, sse_nandv2df3, sse_iorv2df3, sse_xorv2df3): Do not use subregs. (sse_andsf3, sse_nandsf3, sse_xorsf3): Kill. (sse_anddf3, sse_nanddf3, sse_xordf3): Kill. testsuite: PR target/14981 * gcc.dg/pr14981-1.c: New test. From-SVN: r96876 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c6357259836d..425922b1b617 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2005-03-22 Uros Bizjak + + PR target/14981 + Backport from mainline + 2004-02-18 Jan Hubicka + * simplify-rtx.c (simplify_unary_operation): Deal with logicals on + floats. + (simplify_binary_operation): Deal with logicals on floats. + * i386.md (SSE fabs splitters): Emit new patterns. + (SSE cmov splitters): Likewise. + (sse_andv4sf3, sse_nandv4sf3, sse_iorv4sf3, sse_xorv4sf3 + (sse_andv2df3, sse_nandv2df3, sse_iorv2df3, sse_xorv2df3): Do not use + subregs. + (sse_andsf3, sse_nandsf3, sse_xorsf3): Kill. + (sse_anddf3, sse_nanddf3, sse_xordf3): Kill. + 2005-03-20 Marek Michalkiewicz PR target/18551 diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 53589e1613ac..b95f919a25de 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -9688,12 +9688,12 @@ (use (match_operand:V4SF 2 "nonimmediate_operand" "")) (clobber (reg:CC 17))] "reload_completed && SSE_REG_P (operands[0])" - [(set (subreg:TI (match_dup 0) 0) - (xor:TI (match_dup 1) - (match_dup 2)))] + [(set (match_dup 0) + (xor:V4SF (match_dup 1) + (match_dup 2)))] { - operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0); - operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0); + operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0); + operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0); if (operands_match_p (operands[0], operands[2])) { rtx tmp; @@ -9856,13 +9856,12 @@ (use (match_operand:V2DF 2 "nonimmediate_operand" "")) (clobber (reg:CC 17))] "reload_completed && SSE_REG_P (operands[0])" - [(set (subreg:TI (match_dup 0) 0) - (xor:TI (match_dup 1) - (match_dup 2)))] + [(set (match_dup 0) + (xor:V2DF (match_dup 1) + (match_dup 2)))] { operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0); - operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0); - operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0); + operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0); /* Avoid possible reformatting on the operands. */ if (TARGET_SSE_PARTIAL_REGS && !optimize_size) emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0])); @@ -10096,12 +10095,12 @@ (use (match_operand:V4SF 2 "nonimmediate_operand" "")) (clobber (reg:CC 17))] "reload_completed && SSE_REG_P (operands[0])" - [(set (subreg:TI (match_dup 0) 0) - (and:TI (match_dup 1) - (match_dup 2)))] + [(set (match_dup 0) + (and:V4SF (match_dup 1) + (match_dup 2)))] { - operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0); - operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0); + operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0); + operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0); if (operands_match_p (operands[0], operands[2])) { rtx tmp; @@ -10250,13 +10249,12 @@ (use (match_operand:V2DF 2 "nonimmediate_operand" "")) (clobber (reg:CC 17))] "reload_completed && SSE_REG_P (operands[0])" - [(set (subreg:TI (match_dup 0) 0) - (and:TI (match_dup 1) - (match_dup 2)))] + [(set (match_dup 0) + (and:V2DF (match_dup 1) + (match_dup 2)))] { operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0); - operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0); - operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0); + operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0); /* Avoid possible reformatting on the operands. */ if (TARGET_SSE_PARTIAL_REGS && !optimize_size) emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0])); @@ -17074,22 +17072,60 @@ ;; nand op0, op3 - load op3 to op0 if comparison was false ;; or op2, op0 - get the nonzero one into the result. (define_split - [(set (match_operand 0 "register_operand" "") - (if_then_else (match_operator 1 "sse_comparison_operator" - [(match_operand 4 "register_operand" "") - (match_operand 5 "nonimmediate_operand" "")]) - (match_operand 2 "register_operand" "") - (match_operand 3 "register_operand" ""))) + [(set (match_operand:SF 0 "register_operand" "") + (if_then_else (match_operator:SF 1 "sse_comparison_operator" + [(match_operand:SF 4 "register_operand" "") + (match_operand:SF 5 "nonimmediate_operand" "")]) + (match_operand:SF 2 "register_operand" "") + (match_operand:SF 3 "register_operand" ""))) (clobber (match_operand 6 "" "")) (clobber (reg:CC 17))] "SSE_REG_P (operands[0]) && reload_completed" [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)])) - (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0) - (subreg:TI (match_dup 4) 0))) - (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0)) - (subreg:TI (match_dup 3) 0))) - (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0) - (subreg:TI (match_dup 7) 0)))] + (set (match_dup 2) (and:V4SF (match_dup 2) + (match_dup 8))) + (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8)) + (match_dup 3))) + (set (match_dup 0) (ior:V4SF (match_dup 6) + (match_dup 7)))] +{ + /* If op2 == op3, op3 would be clobbered before it is used. */ + if (operands_match_p (operands[2], operands[3])) + { + emit_move_insn (operands[0], operands[2]); + DONE; + } + + PUT_MODE (operands[1], GET_MODE (operands[0])); + if (operands_match_p (operands[0], operands[4])) + operands[6] = operands[4], operands[7] = operands[2]; + else + operands[6] = operands[2], operands[7] = operands[4]; + operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0); + operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0); + operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0); + operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0); + operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0); + operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0); +}) + +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (if_then_else (match_operator:DF 1 "sse_comparison_operator" + [(match_operand:DF 4 "register_operand" "") + (match_operand:DF 5 "nonimmediate_operand" "")]) + (match_operand:DF 2 "register_operand" "") + (match_operand:DF 3 "register_operand" ""))) + (clobber (match_operand 6 "" "")) + (clobber (reg:CC 17))] + "SSE_REG_P (operands[0]) && reload_completed" + [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)])) + (set (match_dup 2) (and:V2DF (match_dup 2) + (match_dup 8))) + (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8)) + (match_dup 3))) + (set (match_dup 0) (ior:V2DF (match_dup 6) + (match_dup 7)))] { if (GET_MODE (operands[2]) == DFmode && TARGET_SSE_PARTIAL_REGS && !optimize_size) @@ -17112,6 +17148,12 @@ operands[6] = operands[4], operands[7] = operands[2]; else operands[6] = operands[2], operands[7] = operands[4]; + operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0); + operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0); + operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0); + operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0); + operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0); + operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0); }) ;; Special case of conditional move we can handle effectively. @@ -17198,18 +17240,55 @@ "#") (define_split - [(set (match_operand 0 "register_operand" "") - (if_then_else (match_operator 1 "comparison_operator" - [(match_operand 4 "nonimmediate_operand" "") - (match_operand 5 "nonimmediate_operand" "")]) - (match_operand 2 "nonmemory_operand" "") - (match_operand 3 "nonmemory_operand" "")))] + [(set (match_operand:SF 0 "register_operand" "") + (if_then_else (match_operator:SF 1 "comparison_operator" + [(match_operand:SF 4 "nonimmediate_operand" "") + (match_operand:SF 5 "nonimmediate_operand" "")]) + (match_operand:SF 2 "nonmemory_operand" "") + (match_operand:SF 3 "nonmemory_operand" "")))] + "SSE_REG_P (operands[0]) && reload_completed + && (const0_operand (operands[2], GET_MODE (operands[0])) + || const0_operand (operands[3], GET_MODE (operands[0])))" + [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)])) + (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))] +{ + PUT_MODE (operands[1], GET_MODE (operands[0])); + if (!sse_comparison_operator (operands[1], VOIDmode) + || !rtx_equal_p (operands[0], operands[4])) + { + rtx tmp = operands[5]; + operands[5] = operands[4]; + operands[4] = tmp; + PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1]))); + } + if (!rtx_equal_p (operands[0], operands[4])) + abort (); + operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0); + if (const0_operand (operands[2], GET_MODE (operands[2]))) + { + operands[7] = operands[3]; + operands[6] = gen_rtx_NOT (V4SFmode, operands[5]); + } + else + { + operands[7] = operands[2]; + operands[6] = operands[0]; + } + operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0); +}) + +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (if_then_else (match_operator:DF 1 "comparison_operator" + [(match_operand:DF 4 "nonimmediate_operand" "") + (match_operand:DF 5 "nonimmediate_operand" "")]) + (match_operand:DF 2 "nonmemory_operand" "") + (match_operand:DF 3 "nonmemory_operand" "")))] "SSE_REG_P (operands[0]) && reload_completed && (const0_operand (operands[2], GET_MODE (operands[0])) || const0_operand (operands[3], GET_MODE (operands[0])))" [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)])) - (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6) - (match_dup 7)))] + (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))] { if (TARGET_SSE_PARTIAL_REGS && !optimize_size && GET_MODE (operands[2]) == DFmode) @@ -17236,19 +17315,18 @@ } if (!rtx_equal_p (operands[0], operands[4])) abort (); - if (const0_operand (operands[2], GET_MODE (operands[0]))) + operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0); + if (const0_operand (operands[2], GET_MODE (operands[2]))) { operands[7] = operands[3]; - operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0], - 0)); + operands[6] = gen_rtx_NOT (V2DFmode, operands[8]); } else { operands[7] = operands[2]; - operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0); + operands[6] = operands[8]; } - operands[7] = simplify_gen_subreg (TImode, operands[7], - GET_MODE (operands[7]), 0); + operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0); }) (define_expand "allocate_stack_worker" @@ -19505,26 +19583,16 @@ ;; of DImode subregs again! ;; SSE1 single precision floating point logical operation (define_expand "sse_andv4sf3" - [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0) - (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0) - (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))] + [(set (match_operand:V4SF 0 "register_operand" "") + (and:V4SF (match_operand:V4SF 1 "register_operand" "") + (match_operand:V4SF 2 "nonimmediate_operand" "")))] "TARGET_SSE" "") (define_insn "*sse_andv4sf3" - [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0) - (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0") - (match_operand:TI 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE - && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" - "andps\t{%2, %0|%0, %2}" - [(set_attr "type" "sselog") - (set_attr "mode" "V4SF")]) - -(define_insn "*sse_andsf3" - [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0) - (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0") - (match_operand:TI 2 "nonimmediate_operand" "xm")))] + [(set (match_operand:V4SF 0 "register_operand" "=x") + (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0") + (match_operand:V4SF 2 "nonimmediate_operand" "xm")))] "TARGET_SSE && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" "andps\t{%2, %0|%0, %2}" @@ -19532,51 +19600,32 @@ (set_attr "mode" "V4SF")]) (define_expand "sse_nandv4sf3" - [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0) - (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)) - (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))] + [(set (match_operand:V4SF 0 "register_operand" "") + (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "")) + (match_operand:V4SF 2 "nonimmediate_operand" "")))] "TARGET_SSE" "") (define_insn "*sse_nandv4sf3" - [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0) - (and:TI (not:TI (match_operand:TI 1 "register_operand" "0")) - (match_operand:TI 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE" - "andnps\t{%2, %0|%0, %2}" - [(set_attr "type" "sselog") - (set_attr "mode" "V4SF")]) - -(define_insn "*sse_nandsf3" - [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0) - (and:TI (not:TI (match_operand:TI 1 "register_operand" "0")) - (match_operand:TI 2 "nonimmediate_operand" "xm")))] + [(set (match_operand:V4SF 0 "register_operand" "=x") + (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0")) + (match_operand:V4SF 2 "nonimmediate_operand" "xm")))] "TARGET_SSE" "andnps\t{%2, %0|%0, %2}" [(set_attr "type" "sselog") (set_attr "mode" "V4SF")]) (define_expand "sse_iorv4sf3" - [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0) - (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0) - (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))] + [(set (match_operand:V4SF 0 "register_operand" "") + (ior:V4SF (match_operand:V4SF 1 "register_operand" "") + (match_operand:V4SF 2 "nonimmediate_operand" "")))] "TARGET_SSE" "") (define_insn "*sse_iorv4sf3" - [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0) - (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0") - (match_operand:TI 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE - && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" - "orps\t{%2, %0|%0, %2}" - [(set_attr "type" "sselog") - (set_attr "mode" "V4SF")]) - -(define_insn "*sse_iorsf3" - [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0) - (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0") - (match_operand:TI 2 "nonimmediate_operand" "xm")))] + [(set (match_operand:V4SF 0 "register_operand" "=x") + (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0") + (match_operand:V4SF 2 "nonimmediate_operand" "xm")))] "TARGET_SSE && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" "orps\t{%2, %0|%0, %2}" @@ -19584,27 +19633,16 @@ (set_attr "mode" "V4SF")]) (define_expand "sse_xorv4sf3" - [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0) - (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0) - (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))] - "TARGET_SSE - && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" + [(set (match_operand:V4SF 0 "register_operand" "") + (xor:V4SF (match_operand:V4SF 1 "register_operand" "") + (match_operand:V4SF 2 "nonimmediate_operand" "")))] + "TARGET_SSE" "") (define_insn "*sse_xorv4sf3" - [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0) - (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0") - (match_operand:TI 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE - && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" - "xorps\t{%2, %0|%0, %2}" - [(set_attr "type" "sselog") - (set_attr "mode" "V4SF")]) - -(define_insn "*sse_xorsf3" - [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0) - (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0") - (match_operand:TI 2 "nonimmediate_operand" "xm")))] + [(set (match_operand:V4SF 0 "register_operand" "=x") + (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0") + (match_operand:V4SF 2 "nonimmediate_operand" "xm")))] "TARGET_SSE && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" "xorps\t{%2, %0|%0, %2}" @@ -19614,26 +19652,16 @@ ;; SSE2 double precision floating point logical operation (define_expand "sse2_andv2df3" - [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0) - (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0) - (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))] + [(set (match_operand:V2DF 0 "register_operand" "") + (and:V2DF (match_operand:V2DF 1 "register_operand" "") + (match_operand:V2DF 2 "nonimmediate_operand" "")))] "TARGET_SSE2" "") (define_insn "*sse2_andv2df3" - [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0) - (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0") - (match_operand:TI 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2 - && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" - "andpd\t{%2, %0|%0, %2}" - [(set_attr "type" "sselog") - (set_attr "mode" "V2DF")]) - -(define_insn "*sse2_andv2df3" - [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0) - (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0") - (match_operand:TI 2 "nonimmediate_operand" "xm")))] + [(set (match_operand:V2DF 0 "register_operand" "=x") + (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0") + (match_operand:V2DF 2 "nonimmediate_operand" "xm")))] "TARGET_SSE2 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" "andpd\t{%2, %0|%0, %2}" @@ -19641,51 +19669,32 @@ (set_attr "mode" "V2DF")]) (define_expand "sse2_nandv2df3" - [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0) - (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)) - (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))] + [(set (match_operand:V2DF 0 "register_operand" "") + (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "")) + (match_operand:V2DF 2 "nonimmediate_operand" "")))] "TARGET_SSE2" "") (define_insn "*sse2_nandv2df3" - [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0) - (and:TI (not:TI (match_operand:TI 1 "register_operand" "0")) - (match_operand:TI 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2" - "andnpd\t{%2, %0|%0, %2}" - [(set_attr "type" "sselog") - (set_attr "mode" "V2DF")]) - -(define_insn "*sse_nandti3_df" - [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0) - (and:TI (not:TI (match_operand:TI 1 "register_operand" "0")) - (match_operand:TI 2 "nonimmediate_operand" "Ym")))] + [(set (match_operand:V2DF 0 "register_operand" "=x") + (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0")) + (match_operand:V2DF 2 "nonimmediate_operand" "xm")))] "TARGET_SSE2" "andnpd\t{%2, %0|%0, %2}" [(set_attr "type" "sselog") (set_attr "mode" "V2DF")]) (define_expand "sse2_iorv2df3" - [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0) - (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0) - (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))] + [(set (match_operand:V2DF 0 "register_operand" "") + (ior:V2DF (match_operand:V2DF 1 "register_operand" "") + (match_operand:V2DF 2 "nonimmediate_operand" "")))] "TARGET_SSE2" "") (define_insn "*sse2_iorv2df3" - [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0) - (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0") - (match_operand:TI 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2 - && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" - "orpd\t{%2, %0|%0, %2}" - [(set_attr "type" "sselog") - (set_attr "mode" "V2DF")]) - -(define_insn "*sse2_iordf3" - [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0) - (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0") - (match_operand:TI 2 "nonimmediate_operand" "xm")))] + [(set (match_operand:V2DF 0 "register_operand" "=x") + (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0") + (match_operand:V2DF 2 "nonimmediate_operand" "xm")))] "TARGET_SSE2 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" "orpd\t{%2, %0|%0, %2}" @@ -19693,26 +19702,16 @@ (set_attr "mode" "V2DF")]) (define_expand "sse2_xorv2df3" - [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0) - (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0) - (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))] + [(set (match_operand:V2DF 0 "register_operand" "") + (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "") + (match_operand:V2DF 2 "nonimmediate_operand" "")))] "TARGET_SSE2" "") (define_insn "*sse2_xorv2df3" - [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0) - (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0") - (match_operand:TI 2 "nonimmediate_operand" "xm")))] - "TARGET_SSE2 - && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" - "xorpd\t{%2, %0|%0, %2}" - [(set_attr "type" "sselog") - (set_attr "mode" "V2DF")]) - -(define_insn "*sse2_xordf3" - [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0) - (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0") - (match_operand:TI 2 "nonimmediate_operand" "xm")))] + [(set (match_operand:V2DF 0 "register_operand" "=x") + (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0") + (match_operand:V2DF 2 "nonimmediate_operand" "xm")))] "TARGET_SSE2 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" "xorpd\t{%2, %0|%0, %2}" diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 91fe8e258e01..bdbc30b24042 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -773,7 +773,16 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode, case FIX: real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL); break; + case NOT: + { + long tmp[4]; + int i; + real_to_target (tmp, &d, GET_MODE (trueop)); + for (i = 0; i < 4; i++) + tmp[i] = ~tmp[i]; + real_from_target (&d, tmp, mode); + } default: abort (); } @@ -1220,60 +1229,91 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode, && GET_CODE (trueop1) == CONST_DOUBLE && mode == GET_MODE (op0) && mode == GET_MODE (op1)) { - REAL_VALUE_TYPE f0, f1, value; - - REAL_VALUE_FROM_CONST_DOUBLE (f0, trueop0); - REAL_VALUE_FROM_CONST_DOUBLE (f1, trueop1); - f0 = real_value_truncate (mode, f0); - f1 = real_value_truncate (mode, f1); + if (code == AND + || code == IOR + || code == XOR) + { + long tmp0[4]; + long tmp1[4]; + REAL_VALUE_TYPE r; + int i; + + real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0), + GET_MODE (op0)); + real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1), + GET_MODE (op1)); + for (i = 0; i < 4; i++) + { + if (code == AND) + tmp0[i] &= tmp1[i]; + else if (code == IOR) + tmp0[i] |= tmp1[i]; + else if (code == XOR) + tmp0[i] ^= tmp1[i]; + else + abort (); + } + real_from_target (&r, tmp0, mode); + return CONST_DOUBLE_FROM_REAL_VALUE (r, mode); + } + else + { + REAL_VALUE_TYPE f0, f1, value; - if (HONOR_SNANS (mode) - && (REAL_VALUE_ISNAN (f0) || REAL_VALUE_ISNAN (f1))) - return 0; + REAL_VALUE_FROM_CONST_DOUBLE (f0, trueop0); + REAL_VALUE_FROM_CONST_DOUBLE (f1, trueop1); + f0 = real_value_truncate (mode, f0); + f1 = real_value_truncate (mode, f1); - if (code == DIV - && REAL_VALUES_EQUAL (f1, dconst0) - && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode))) - return 0; + if (HONOR_SNANS (mode) + && (REAL_VALUE_ISNAN (f0) || REAL_VALUE_ISNAN (f1))) + return 0; - if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode) - && flag_trapping_math - && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1)) - { - int s0 = REAL_VALUE_NEGATIVE (f0); - int s1 = REAL_VALUE_NEGATIVE (f1); + if (code == DIV + && REAL_VALUES_EQUAL (f1, dconst0) + && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode))) + return 0; - switch (code) + if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode) + && flag_trapping_math + && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1)) { - case PLUS: - /* Inf + -Inf = NaN plus exception. */ - if (s0 != s1) - return 0; - break; - case MINUS: - /* Inf - Inf = NaN plus exception. */ - if (s0 == s1) - return 0; - break; - case DIV: - /* Inf / Inf = NaN plus exception. */ - return 0; - default: - break; + int s0 = REAL_VALUE_NEGATIVE (f0); + int s1 = REAL_VALUE_NEGATIVE (f1); + + switch (code) + { + case PLUS: + /* Inf + -Inf = NaN plus exception. */ + if (s0 != s1) + return 0; + break; + case MINUS: + /* Inf - Inf = NaN plus exception. */ + if (s0 == s1) + return 0; + break; + case DIV: + /* Inf / Inf = NaN plus exception. */ + return 0; + default: + break; + } } - } - if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode) - && flag_trapping_math - && ((REAL_VALUE_ISINF (f0) && REAL_VALUES_EQUAL (f1, dconst0)) - || (REAL_VALUE_ISINF (f1) && REAL_VALUES_EQUAL (f0, dconst0)))) - /* Inf * 0 = NaN plus exception. */ - return 0; + if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode) + && flag_trapping_math + && ((REAL_VALUE_ISINF (f0) && REAL_VALUES_EQUAL (f1, dconst0)) + || (REAL_VALUE_ISINF (f1) + && REAL_VALUES_EQUAL (f0, dconst0)))) + /* Inf * 0 = NaN plus exception. */ + return 0; - REAL_ARITHMETIC (value, rtx_to_tree_code (code), f0, f1); + REAL_ARITHMETIC (value, rtx_to_tree_code (code), f0, f1); - value = real_value_truncate (mode, value); - return CONST_DOUBLE_FROM_REAL_VALUE (value, mode); + value = real_value_truncate (mode, value); + return CONST_DOUBLE_FROM_REAL_VALUE (value, mode); + } } /* We can fold some multi-word operations. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c4fdd16d1ecc..bf9b4f8cd57a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-03-22 Uros Bizjak + + PR target/14981 + * gcc.dg/pr14981-1.c: New test. + 2005-03-21 Paolo Carlini PR c++/20147 diff --git a/gcc/testsuite/gcc.dg/pr14981-1.c b/gcc/testsuite/gcc.dg/pr14981-1.c new file mode 100644 index 000000000000..7d5bde9e5665 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr14981-1.c @@ -0,0 +1,12 @@ +/* PR target/14981 */ +/* PR target/20051 */ +/* Test case reduced by Ferdinand */ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-options "-O2 -msse" } */ +typedef float v4sf __attribute__ ((vector_size (16))); + +void foo(float* y) +{ + v4sf x = __builtin_ia32_xorps (x,x); + __builtin_ia32_storeaps (y, x); +}