This patch prevents the special overriding of the complex float128 multiply/divide functions from being run twice if there are clone or target attributes. I wasn't aware that the hook used to initialize the built-in functions is run each time you change the target options. The built-in function handling aborts if the name had already been set.
I have tested this on a little endian power8 sysytem using two builds with long double set to IEEE and IBM 128-bit. This patch fixes testsuite errors from using the clone or target attributes. Can I install it in the trunk and GCC 8.x branches? [gcc] 2018-06-20 Michael Meissner <meiss...@linux.ibm.com> * config/rs6000/rs6000.c (init_float128_ieee): Prevent complex multiply and divide external functions from being created more than once. -- Michael Meissner, IBM IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 261574) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -17892,9 +17892,14 @@ init_float128_ieee (machine_mode mode) { if (FLOAT128_VECTOR_P (mode)) { - /* Set up to call __mulkc3 and __divkc3 under -mabi=ieeelongdouble. */ - if (mode == TFmode && TARGET_IEEEQUAD) + static bool complex_muldiv_init_p = false; + + /* Set up to call __mulkc3 and __divkc3 under -mabi=ieeelongdouble. If + we have clone or target attributes, this will be called a second + time. We want to create the built-in function only once. */ + if (mode == TFmode && TARGET_IEEEQUAD && !complex_muldiv_init_p) { + complex_muldiv_init_p = true; built_in_function fncode_mul = (built_in_function) (BUILT_IN_COMPLEX_MUL_MIN + TCmode - MIN_MODE_COMPLEX_FLOAT);