diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 35fd66e..bc419ff 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -13554,6 +13554,14 @@ [(set_attr "type" "ssemov") (set_attr "mode" "V2SF,V4SF,V2SF")]) +;; Convert highpart SUBREG in sse2_storehpd or *vec_extractv2df_1_sse. +(define_split + [(set (match_operand:DF 0 "register_operand") + (subreg:DF (match_operand:V2DF 1 "register_operand") 8))] + "TARGET_SSE" + [(set (match_dup 0) + (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))]) + ;; Avoid combining registers from different units in a single alternative, ;; see comment above inline_secondary_memory_needed function in i386.cc (define_insn "sse2_storelpd" @@ -13599,6 +13607,14 @@ [(set_attr "type" "ssemov") (set_attr "mode" "V2SF,V4SF,V2SF")]) +;; Convert lowpart SUBREG into sse2_storelpd or *vec_extractv2df_0_sse. +(define_split + [(set (match_operand:DF 0 "register_operand") + (subreg:DF (match_operand:V2DF 1 "register_operand") 0))] + "TARGET_SSE" + [(set (match_dup 0) + (vec_select:DF (match_dup 1) (parallel [(const_int 0)])))]) + (define_expand "sse2_loadhpd_exp" [(set (match_operand:V2DF 0 "nonimmediate_operand") (vec_concat:V2DF diff --git a/gcc/testsuite/gcc.target/i386/pr88873.c b/gcc/testsuite/gcc.target/i386/pr88873.c index d893aac..a3a7ef2 100644 --- a/gcc/testsuite/gcc.target/i386/pr88873.c +++ b/gcc/testsuite/gcc.target/i386/pr88873.c @@ -9,3 +9,5 @@ s_t foo (s_t a, s_t b, s_t c) } /* { dg-final { scan-assembler-times "vpunpcklqdq" 3 } } */ +/* { dg-final { scan-assembler "vunpckhpd" } } */ +/* { dg-final { scan-assembler-not "rsp" } } */