https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110136
Bug ID: 110136 Summary: After optimization, the $r1 register will be broken when jumping to the jump table, resulting in a significant increase in the false prediction rate of branch prediction. Product: gcc Version: 12.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: lto Assignee: unassigned at gcc dot gnu.org Reporter: chenglulu at loongson dot cn CC: marxin at gcc dot gnu.org Target Milestone: --- Target: loongarch64-*-linux Created attachment 55267 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55267&action=edit perlbench.ltrans15.ltrans.args.0 tag: releases/gcc-12.2.0 The code here replicates the problem. $ ./libexec/gcc/loongarch64-linux-gnu/12.2.0/lto1 -quiet -dumpbase ./perlbench.ltrans15.ltrans -mabi=lp64d -march=loongarch64 -mfpu=64 -mcmodel=normal -mtune=loongarch64 -g -g -Ofast -Ofast -version -fno-openmp -fno-openacc -fcf-protection=none -fno-omit-frame-pointer -funroll-all-loops -fltrans @./perlbench.ltrans15.ltrans.args.0 -fdump-rtl-all -o ./perlbench.ltrans15.ltrans.s -fpie Perl_sv_upgrade: ... 5908 addi.w $r18,$r0,15 # 0xf 5909 bgtu $r23,$r18,.L502 5910 la.local $r16,.L504 5911 slli.d $r19,$r23,3 5912 ldx.d $r20,$r16,$r19 5913 add.d $r1,$r16,$r20 5914 jr $r1 ... In the regrename passover optimization, replace the registers of lines 5193 and 5194 with $r1. I tried debugging and found that the problem would be solved if hook HARD_REGNO_RENAME_OK was defined, but found that this was just an accident and there is no guarantee that this register will not be replaced with $r1 when jumping to the jump table. The patch that defines the HARD_REGNO_RENAME_OK is as follows: diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 5c9a33c14f7..0df0ae15c3e 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -5782,6 +5782,19 @@ loongarch_starting_frame_offset (void) return crtl->outgoing_args_size; } +/* Return nonzero if register FROM_REGNO can be renamed to register + TO_REGNO. */ + +bool +loongarch_hard_regno_rename_ok (unsigned from_regno ATTRIBUTE_UNUSED, + unsigned to_regno) +{ + return df_regs_ever_live_p (to_regno); +} + /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" diff --git a/gcc/config/loongarch/loongarch.h b/gcc/config/loongarch/loongarch.h index f9de9a6e4fb..b22b439eaac 100644 --- a/gcc/config/loongarch/loongarch.h +++ b/gcc/config/loongarch/loongarch.h @@ -563,6 +563,8 @@ enum reg_class #define IMM_BITS 12 #define IMM_REACH (1LL << IMM_BITS) +#define HARD_REGNO_RENAME_OK(FROM, TO) loongarch_hard_regno_rename_ok (FROM, TO) + /* True if VALUE is an unsigned 6-bit number. */ Is there a way to make sure that the $r1 register is not corrupted when jumping to the table?