Skip to content

Commit

Permalink
cmd/compile: upgrade ssa to do (int or float) -> complex
Browse files Browse the repository at this point in the history
Generic instantiations can produce conversions from constant
literal ints or floats to complex values. We could constant literals
during instantiation, but it is just as easy to upgrade the code
generator to do the conversions.

Fixes #50193

Change-Id: I24bdc09226c8e868f6282e0e4057ba6c3ad5c41a
Reviewed-on: https://go-review.googlesource.com/c/go/+/372514
Trust: Keith Randall <[email protected]>
Run-TryBot: Keith Randall <[email protected]>
Trust: Dan Scales <[email protected]>
Reviewed-by: Dan Scales <[email protected]>
Reviewed-by: Cherry Mui <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
  • Loading branch information
randall77 committed Dec 16, 2021
1 parent 6e7c691 commit d107aa2
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 25 deletions.
57 changes: 32 additions & 25 deletions src/cmd/compile/internal/ssagen/ssa.go
Original file line number Diff line number Diff line change
Expand Up @@ -2446,6 +2446,38 @@ func (s *state) conv(n ir.Node, v *ssa.Value, ft, tt *types.Type) *ssa.Value {
return s.newValue1(op, tt, v)
}

if ft.IsComplex() && tt.IsComplex() {
var op ssa.Op
if ft.Size() == tt.Size() {
switch ft.Size() {
case 8:
op = ssa.OpRound32F
case 16:
op = ssa.OpRound64F
default:
s.Fatalf("weird complex conversion %v -> %v", ft, tt)
}
} else if ft.Size() == 8 && tt.Size() == 16 {
op = ssa.OpCvt32Fto64F
} else if ft.Size() == 16 && tt.Size() == 8 {
op = ssa.OpCvt64Fto32F
} else {
s.Fatalf("weird complex conversion %v -> %v", ft, tt)
}
ftp := types.FloatForComplex(ft)
ttp := types.FloatForComplex(tt)
return s.newValue2(ssa.OpComplexMake, tt,
s.newValueOrSfCall1(op, ttp, s.newValue1(ssa.OpComplexReal, ftp, v)),
s.newValueOrSfCall1(op, ttp, s.newValue1(ssa.OpComplexImag, ftp, v)))
}

if tt.IsComplex() { // and ft is not complex
// Needed for generics support - can't happen in normal Go code.
et := types.FloatForComplex(tt)
v = s.conv(n, v, ft, et)
return s.newValue2(ssa.OpComplexMake, tt, v, s.zeroVal(et))
}

if ft.IsFloat() || tt.IsFloat() {
conv, ok := fpConvOpToSSA[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]
if s.config.RegSize == 4 && Arch.LinkArch.Family != sys.MIPS && !s.softFloat {
Expand Down Expand Up @@ -2519,31 +2551,6 @@ func (s *state) conv(n ir.Node, v *ssa.Value, ft, tt *types.Type) *ssa.Value {
return nil
}

if ft.IsComplex() && tt.IsComplex() {
var op ssa.Op
if ft.Size() == tt.Size() {
switch ft.Size() {
case 8:
op = ssa.OpRound32F
case 16:
op = ssa.OpRound64F
default:
s.Fatalf("weird complex conversion %v -> %v", ft, tt)
}
} else if ft.Size() == 8 && tt.Size() == 16 {
op = ssa.OpCvt32Fto64F
} else if ft.Size() == 16 && tt.Size() == 8 {
op = ssa.OpCvt64Fto32F
} else {
s.Fatalf("weird complex conversion %v -> %v", ft, tt)
}
ftp := types.FloatForComplex(ft)
ttp := types.FloatForComplex(tt)
return s.newValue2(ssa.OpComplexMake, tt,
s.newValueOrSfCall1(op, ttp, s.newValue1(ssa.OpComplexReal, ftp, v)),
s.newValueOrSfCall1(op, ttp, s.newValue1(ssa.OpComplexImag, ftp, v)))
}

s.Fatalf("unhandled OCONV %s -> %s", ft.Kind(), tt.Kind())
return nil
}
Expand Down
32 changes: 32 additions & 0 deletions test/typeparam/issue50193.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// run -gcflags=-G=3

// Copyright 2021 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.

package main

import (
"constraints"
"fmt"
)

func zero[T constraints.Complex]() T {
return T(0)
}
func pi[T constraints.Complex]() T {
return T(3.14)
}
func sqrtN1[T constraints.Complex]() T {
return T(-1i)
}

func main() {
fmt.Println(zero[complex128]())
fmt.Println(pi[complex128]())
fmt.Println(sqrtN1[complex128]())
fmt.Println(zero[complex64]())
fmt.Println(pi[complex64]())
fmt.Println(sqrtN1[complex64]())
}

6 changes: 6 additions & 0 deletions test/typeparam/issue50193.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
(0+0i)
(3.14+0i)
(0-1i)
(0+0i)
(3.14+0i)
(0-1i)

0 comments on commit d107aa2

Please sign in to comment.