[PATCH] testsuite (committed) check_effective_target_broken_cplxf_arg

Janis Johnson janis187@us.ibm.com
Sat Feb 12 11:30:00 GMT 2005


A PowerPC-64 ELF ABI fix in GCC 3.4.0 changes argument passing for
complex float, which creates an incompatibility between programs
compiled with that fix and libm built with an earlier version of GCC.
This causes several test failures for mainline GCC when the test
system has an older libm.

This patch adds a new effective-target keyword to detect this
incompatibility so that affected tests can be marked XFAIL.  The tests
themselves are for gfortran and libstdc++; I'll submit patches to them
separately.

Tested with the to-be-submitted patches to gfortran and libstdc++ tests
with -m32 and -m64 on powerpc64-unknown-linux-gnu, on a system with an
incompatible libm and one with a compatible libm.  Checked in on mainline.

2005-02-11  Janis Johnson  <janis187@us.ibm.com>

	* lib/target-supports.exp (check_effective_target_broken_cplxf_arg):
	New.

Index: gcc/testsuite/lib/target-supports.exp
===================================================================
RCS file: /opt/gcc-cvs/gcc/gcc/testsuite/lib/target-supports.exp,v
retrieving revision 1.39
diff -u -p -r1.39 target-supports.exp
--- gcc/testsuite/lib/target-supports.exp	24 Jan 2005 18:24:02 -0000	1.39
+++ gcc/testsuite/lib/target-supports.exp	10 Feb 2005 18:53:46 -0000
@@ -386,6 +386,92 @@ proc check_vmx_hw_available { } {
     return $vmx_hw_available_saved
 }
 
+# GCC 3.4.0 for powerpc64-*-linux* included an ABI fix for passing
+# complex float arguments.  This affects gfortran tests that call cabsf
+# in libm built by an earlier compiler.  Return 1 if libm uses the same
+# argument passing as the compiler under test, 0 otherwise.
+#
+# When the target name changes, replace the cached result.
+
+proc check_effective_target_broken_cplxf_arg { } {
+    global et_broken_cplxf_arg_saved
+    global et_broken_cplxf_arg_target_name
+    global tool
+
+    # Skip the work for targets known not to be affected.
+    if { ![istarget powerpc64-*-linux*] } {
+	return 0
+    } elseif { [is-effective-target ilp32] } {
+	return 0
+    }
+
+    if { ![info exists et_broken_cplxf_arg_target_name] } {
+	set et_broken_cplxf_arg_target_name ""
+    }
+
+    # If the target has changed since we set the cached value, clear it.
+    set current_target [current_target_name]
+    if { $current_target != $et_broken_cplxf_arg_target_name } {
+	verbose "check_effective_target_broken_cplxf_arg: `$et_broken_cplxf_arg_target_name'" 2
+	set et_broken_cplxf_arg_target_name $current_target
+	if [info exists et_broken_cplxf_arg_saved] {
+	    verbose "check_effective_target_broken_cplxf_arg: removing cached result" 2
+	    unset et_broken_cplxf_arg_saved
+	}
+    }
+
+    if [info exists et_broken_cplxf_arg_saved] {
+	verbose "check_effective_target_broken_cplxf_arg: using cached result" 2
+    } else {
+	set et_broken_cplxf_arg_saved 0
+	# This is only known to affect one target.
+	if { ![istarget powerpc64-*-linux*] || ![is-effective-target lp64] } {
+	    set et_broken_cplxf_arg_saved 0
+	    verbose "check_effective_target_broken_cplxf_arg: caching 0" 2
+	    return $et_broken_cplxf_arg_saved
+	}
+
+	# Set up, compile, and execute a C test program that calls cabsf.
+	set src cabsf[pid].c
+	set exe cabsf[pid].x
+
+	set f [open $src "w"]
+	puts $f "#include <complex.h>"
+	puts $f "extern void abort (void);"
+	puts $f "float fabsf (float);"
+	puts $f "float cabsf (_Complex float);"
+	puts $f "int main ()"
+	puts $f "{"
+	puts $f "  _Complex float cf;"
+	puts $f "  float f;"
+	puts $f "  cf = 3 + 4.0fi;"
+	puts $f "  f = cabsf (cf);"
+	puts $f "  if (fabsf (f - 5.0) > 0.0001) abort ();"
+	puts $f "  return 0;"
+	puts $f "}"
+	close $f
+
+	set lines [${tool}_target_compile $src $exe executable "-lm"]
+	file delete $src
+
+	if [string match "" $lines] {
+	    # No error message, compilation succeeded.
+	    set result [${tool}_load "./$exe" "" ""]
+	    set status [lindex $result 0]
+	    remote_file build delete $exe
+
+	    verbose "check_effective_target_broken_cplxf_arg: status is <$status>" 2
+
+	    if { $status != "pass" } {
+		set et_broken_cplxf_arg_saved 1
+	    }
+	} else {
+	    verbose "check_effective_target_broken_cplxf_arg: compilation failed" 2
+	}
+    }
+    return $et_broken_cplxf_arg_saved
+}
+
 proc check_alpha_max_hw_available { } {
     global alpha_max_hw_available_saved
     global tool



More information about the Gcc-patches mailing list