From cd34d5f2c40f3c65407f4b0bee0b49fc84e4a4ab Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 1 Dec 2020 18:59:18 -0800 Subject: compiler: defer to middle-end for complex division Go used to use slightly different semantics than C99 for complex division, so we used runtime routines to handle the different. The gc compiler has changes its behavior to match C99, so changes ours as well. For golang/go#14644 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/274213 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 21 - gcc/go/gofrontend/runtime.def | 6 - gcc/testsuite/go.test/test/cmplxdivide.c | 87 +- gcc/testsuite/go.test/test/cmplxdivide.go | 27 +- gcc/testsuite/go.test/test/cmplxdivide1.go | 6511 ++++++++++++++++++---------- 6 files changed, 4171 insertions(+), 2483 deletions(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 183e5ca..f55daf7 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -6b01f8cdc11d86bd98165c91d6ae101bcf6b9e1a +5364d15082de77d2759a01f254208d4cb4f579e3 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 23caf61..50574c2 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -6979,27 +6979,6 @@ Binary_expression::do_get_backend(Translate_context* context) // been converted to a String_concat_expression in do_lower. go_assert(!left_type->is_string_type()); - // For complex division Go might want slightly different results than the - // backend implementation provides, so we have our own runtime routine. - if (this->op_ == OPERATOR_DIV && this->left_->type()->complex_type() != NULL) - { - Runtime::Function complex_code; - switch (this->left_->type()->complex_type()->bits()) - { - case 64: - complex_code = Runtime::COMPLEX64_DIV; - break; - case 128: - complex_code = Runtime::COMPLEX128_DIV; - break; - default: - go_unreachable(); - } - Expression* complex_div = - Runtime::make_call(complex_code, loc, 2, this->left_, this->right_); - return complex_div->get_backend(context); - } - Bexpression* left = this->left_->get_backend(context); Bexpression* right = this->right_->get_backend(context); diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def index 9a3c680..4b606a6 100644 --- a/gcc/go/gofrontend/runtime.def +++ b/gcc/go/gofrontend/runtime.def @@ -62,12 +62,6 @@ DEF_GO_RUNTIME(STRINGTOSLICERUNE, "runtime.stringtoslicerune", P2(POINTER, STRING), R1(SLICE)) -// Complex division. -DEF_GO_RUNTIME(COMPLEX64_DIV, "__go_complex64_div", - P2(COMPLEX64, COMPLEX64), R1(COMPLEX64)) -DEF_GO_RUNTIME(COMPLEX128_DIV, "__go_complex128_div", - P2(COMPLEX128, COMPLEX128), R1(COMPLEX128)) - // Make a slice. DEF_GO_RUNTIME(MAKESLICE, "runtime.makeslice", P3(TYPE, INT, INT), R1(POINTER)) diff --git a/gcc/testsuite/go.test/test/cmplxdivide.c b/gcc/testsuite/go.test/test/cmplxdivide.c index 12dc4f1..89a2868 100644 --- a/gcc/testsuite/go.test/test/cmplxdivide.c +++ b/gcc/testsuite/go.test/test/cmplxdivide.c @@ -1,8 +1,19 @@ -// Copyright 2010 The Go Authors. All rights reserved. +// Copyright 2010 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// gcc '-std=c99' cmplxdivide.c && a.out >cmplxdivide1.go +// This C program generates the file cmplxdivide1.go. It uses the +// output of the operations by C99 as the reference to check +// the implementation of complex numbers in Go. +// The generated file, cmplxdivide1.go, is compiled along +// with the driver cmplxdivide.go (the names are confusing +// and unimaginative) to run the actual test. This is done by +// the usual test runner. +// +// The file cmplxdivide1.go is checked in to the repository, but +// if it needs to be regenerated, compile and run this C program +// like this: +// gcc '-std=c99' cmplxdivide.c && a.out >cmplxdivide1.go #include #include @@ -12,50 +23,63 @@ #define nelem(x) (sizeof(x)/sizeof((x)[0])) double f[] = { - 0, - 1, - -1, - 2, + 0.0, + -0.0, + 1.0, + -1.0, + 2.0, NAN, INFINITY, -INFINITY, }; -char* -fmt(double g) -{ +char* fmt(double g) { static char buf[10][30]; static int n; char *p; - + p = buf[n++]; - if(n == 10) + if(n == 10) { n = 0; + } + sprintf(p, "%g", g); - if(strcmp(p, "-0") == 0) - strcpy(p, "negzero"); - return p; -} -int -iscnan(double complex d) -{ - return !isinf(creal(d)) && !isinf(cimag(d)) && (isnan(creal(d)) || isnan(cimag(d))); -} + if(strcmp(p, "0") == 0) { + strcpy(p, "zero"); + return p; + } + + if(strcmp(p, "-0") == 0) { + strcpy(p, "-zero"); + return p; + } -double complex zero; // attempt to hide zero division from gcc + return p; +} -int -main(void) -{ +int main(void) { int i, j, k, l; double complex n, d, q; - + printf("// skip\n"); printf("// # generated by cmplxdivide.c\n"); printf("\n"); printf("package main\n"); - printf("var tests = []Test{\n"); + printf("\n"); + printf("import \"math\"\n"); + printf("\n"); + printf("var (\n"); + printf("\tnan = math.NaN()\n"); + printf("\tinf = math.Inf(1)\n"); + printf("\tzero = 0.0\n"); + printf(")\n"); + printf("\n"); + printf("var tests = []struct {\n"); + printf("\tf, g complex128\n"); + printf("\tout complex128\n"); + printf("}{\n"); + for(i=0; i