From 0c016888ffd569c4b70722cf7df2efcc003f397b Mon Sep 17 00:00:00 2001 From: "Vladimir N. Makarov" Date: Fri, 18 Mar 2022 14:23:40 -0400 Subject: [PATCH] [PR104961] LRA: split hard reg for reload pseudo with clobber. Splitting hard register live range did not work for subreg of a multi-reg reload pseudo. Reload insns for such pseudo contain clobber of the pseudo and splitting did not take this into account. The patch fixes it. gcc/ChangeLog: PR rtl-optimization/104961 * lra-assigns.cc (find_reload_regno_insns): Process reload pseudo clobber. gcc/testsuite/ChangeLog: PR rtl-optimization/104961 * gcc.target/i386/pr104961.c: New. --- gcc/lra-assigns.cc | 33 ++++++++++++++++++-------------- gcc/testsuite/gcc.target/i386/pr104961.c | 15 +++++++++++++++ 2 files changed, 34 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr104961.c diff --git a/gcc/lra-assigns.cc b/gcc/lra-assigns.cc index ab3a6e6..af30a67 100644 --- a/gcc/lra-assigns.cc +++ b/gcc/lra-assigns.cc @@ -1706,7 +1706,8 @@ find_reload_regno_insns (int regno, rtx_insn * &start, rtx_insn * &finish) { unsigned int uid; bitmap_iterator bi; - int n = 0; + int insns_num = 0; + bool clobber_p = false; rtx_insn *prev_insn, *next_insn; rtx_insn *start_insn = NULL, *first_insn = NULL, *second_insn = NULL; @@ -1714,28 +1715,32 @@ find_reload_regno_insns (int regno, rtx_insn * &start, rtx_insn * &finish) { if (start_insn == NULL) start_insn = lra_insn_recog_data[uid]->insn; - n++; + if (GET_CODE (PATTERN (lra_insn_recog_data[uid]->insn)) == CLOBBER) + clobber_p = true; + else + insns_num++; } - /* For reload pseudo we should have at most 3 insns referring for + /* For reload pseudo we should have at most 3 insns besides clobber referring for it: input/output reload insns and the original insn. */ - if (n > 3) + if (insns_num > 3) return false; - if (n > 1) + if (clobber_p) + insns_num++; + if (insns_num > 1) { for (prev_insn = PREV_INSN (start_insn), next_insn = NEXT_INSN (start_insn); - n != 1 && (prev_insn != NULL || next_insn != NULL); ) + insns_num != 1 && (prev_insn != NULL || next_insn != NULL); ) { - if (prev_insn != NULL && first_insn == NULL) + if (prev_insn != NULL) { - if (! bitmap_bit_p (&lra_reg_info[regno].insn_bitmap, - INSN_UID (prev_insn))) - prev_insn = PREV_INSN (prev_insn); - else + if (bitmap_bit_p (&lra_reg_info[regno].insn_bitmap, + INSN_UID (prev_insn))) { first_insn = prev_insn; - n--; + insns_num--; } + prev_insn = PREV_INSN (prev_insn); } if (next_insn != NULL && second_insn == NULL) { @@ -1745,11 +1750,11 @@ find_reload_regno_insns (int regno, rtx_insn * &start, rtx_insn * &finish) else { second_insn = next_insn; - n--; + insns_num--; } } } - if (n > 1) + if (insns_num > 1) return false; } start = first_insn != NULL ? first_insn : start_insn; diff --git a/gcc/testsuite/gcc.target/i386/pr104961.c b/gcc/testsuite/gcc.target/i386/pr104961.c new file mode 100644 index 0000000..11ea95a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr104961.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-Og" } */ + +__int128 i; + +void bar (int); + +void +foo (int a, char b, _Complex unsigned char c) +{ + __int128 j = i * i; + c -= 1; + bar (j); + bar (__imag__ c); +} -- 2.7.4