https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63191
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org, | |uros at gcc dot gnu.org --- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Given say: typedef int X; struct Z { Z(const X* x1, X x2, X x3) : x1_(x1), x2_(x2), x3_(x3) {} const X* x1_; X x2_; X x3_; }; static const X Xs0[] = {}; static const X Xs1[] = {}; static const X Xs2[] = {}; static const X Xs3[] = {}; static const X Xs4[] = {}; static const X Xs5[] = {}; static const X Xs6[] = {}; static const X Xs7[] = {}; static const X Xs8[] = {}; static const X Xs9[] = {}; static const Z Zs[] = { Z(Xs1,1,1), Z(Xs2,2,1), Z(Xs3,2,1), Z(Xs4,1,1), Z(Xs5,1,1),Z(Xs6,8,1), Z(Xs7,1,1),Z(Xs8,5,1), Z(Xs9,1,1),Z(Xs0,7,1) }; const Z *p = &Zs[0]; (the last line is there so that everything is not optimized away), I'm seeing that on x86_64-linux with -m64 -O2 -fpic we actually CSE all those (symbol_ref:DI "_ZL2Zs"), because it has cost of 6 (rtx_cost on that (symbol_ref, DImode, SET, 1) yields 3), while with -m32 -O2 -fpic we don't, because it has cost of 0. But it is more confusing that we actually return 3 on -m64 -fpic, x86_64_nonimmediate_operand has: /* For certain code models, the symbolic references are known to fit. in CM_SMALL_PIC model we know it fits if it is local to the shared library. Don't count TLS SYMBOL_REFs here, since they should fit only if inside of UNSPEC handled below. */ return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_KERNEL || (ix86_cmodel == CM_MEDIUM && !SYMBOL_REF_FAR_ADDR_P (op))); So it talks about ix86_cmodel of CM_SMALL_PIC, but then actually doesn't do anything for it. Perhaps it is right that foo(%rip) is not considered x86_64_nonimmediate_operand, but perhaps it should still have zero cost. That would of course make this PR likely worse even on x86_64 -m64.