Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong BinOp code generation on int/float and untyped #961

Open
cpunion opened this issue Jan 15, 2025 · 0 comments
Open

Wrong BinOp code generation on int/float and untyped #961

cpunion opened this issue Jan 15, 2025 · 0 comments

Comments

@cpunion
Copy link
Contributor

cpunion commented Jan 15, 2025

  • Wrong BinOp code generation on int/float and untyped
  • Inconsistent overflow result with Go
    • Max int8 + 1: 128
    • uint32 max -> float64 -> int32: 0
package main

import (
	"fmt"
)

func main() {
	// Untyped constants
	const (
		untypedInt     = 42
		untypedFloat   = 3.14
		untypedComplex = 1 + 2i
	)

	// Typed variables
	var (
		i8  int8  = 64
		i16 int16 = 1000
		i32 int32 = 70000
		i64 int64 = 1<<32 - 1

		u8  uint8  = 200
		u16 uint16 = 50000
		u32 uint32 = 4000000000
		u64 uint64 = 1<<64 - 1

		f32 float32 = 3.14159
		f64 float64 = 3.14159265359

		c64  complex64  = 1 + 2i
		c128 complex128 = 1 + 2i
	)

	fmt.Println("0. Special Cases:")
	// Integer overflow
	var i8max int8 = 127
	var i8min int8 = -128
	var u8max uint8 = 255
	fmt.Printf("Max int8 + 1: %d\n", i8max+1)  // Overflow
	fmt.Printf("Max uint8 + 1: %d\n", u8max+1) // Overflow
	fmt.Printf("Min int8 - 1: %d\n", i8min-1)  // Underflow

	// Float precision
	fmt.Printf("Large float32: %.1f + 1 = %.1f\n", float32(16777216), float32(16777216)+1)

	// Large number conversions
	var bigUint32 uint32 = 0xFFFFFFFF // max uint32
	fmt.Printf("uint32 max -> float64 -> int32: %d\n", int32(float64(bigUint32)))

	// Complex special cases
	fmt.Printf("Complex division: %v\n", complex128(c64)/c128)
	fmt.Printf("Complex multiplication: %v\n", c64*complex64(c128))

	fmt.Println("\n1. Untyped Constants with Typed Variables:")
	fmt.Printf("untypedInt + i32: %d (type %T)\n", untypedInt+i32, untypedInt+i32)
	fmt.Printf("untypedFloat + f32: %f (type %T)\n", untypedFloat+f32, untypedFloat+f32)
	fmt.Printf("untypedComplex + c64: %v (type %T)\n", untypedComplex+c64, untypedComplex+c64)

	fmt.Println("\n2. Mixed Integer Operations:")
	// Signed integers
	fmt.Printf("i8 + i16: %d (type %T)\n", int16(i8)+i16, int16(i8)+i16)
	fmt.Printf("i16 + i32: %d (type %T)\n", int32(i16)+i32, int32(i16)+i32)
	fmt.Printf("i32 + i64: %d (type %T)\n", int64(i32)+i64, int64(i32)+i64)

	// Unsigned integers
	fmt.Printf("u8 + u16: %d (type %T)\n", uint16(u8)+u16, uint16(u8)+u16)
	fmt.Printf("u16 + u32: %d (type %T)\n", uint32(u16)+u32, uint32(u16)+u32)
	fmt.Printf("u32 + u64: %d (type %T)\n", uint64(u32)+u64, uint64(u32)+u64)

	// Mixed signed/unsigned
	fmt.Printf("i32 + u32: %d (type %T)\n", int64(i32)+int64(u32), int64(i32)+int64(u32))

	fmt.Println("\n3. Mixed Float Operations:")
	fmt.Printf("f32 + f64: %f (type %T)\n", float64(f32)+f64, float64(f32)+f64)
	fmt.Printf("i32 + f64: %f (type %T)\n", float64(i32)+f64, float64(i32)+f64)
	fmt.Printf("u32 + f32: %f (type %T)\n", float32(u32)+f32, float32(u32)+f32)

	fmt.Println("\n4. Complex Number Operations:")
	fmt.Printf("c64 + c128: %v (type %T)\n", complex128(c64)+c128, complex128(c64)+c128)
	fmt.Printf("f64 + c128: %v (type %T)\n", complex(f64, 0)+c128, complex(f64, 0)+c128)
	fmt.Printf("i32 + c64: %v (type %T)\n", complex(float32(i32), 0)+c64, complex(float32(i32), 0)+c64)
}
$ llgo cmptest ./binop
=> Result of output
0. Special Cases:
Max int8 + 1: 128
Max uint8 + 1: 0
Min int8 - 1: 127
Large float32: 16777216.0 + 1 = 16777216.0
uint32 max -> float64 -> int32: 0
Complex division: (1+0i)
Complex multiplication: (-3+4i)

1. Untyped Constants with Typed Variables:

=> Expected output
0. Special Cases:
Max int8 + 1: -128
Max uint8 + 1: 0
Min int8 - 1: 127
Large float32: 16777216.0 + 1 = 16777216.0
uint32 max -> float64 -> int32: 2147483647
Complex division: (1+0i)
Complex multiplication: (-3+4i)

1. Untyped Constants with Typed Variables:
untypedInt + i32: 70042 (type int32)
untypedFloat + f32: 6.281590 (type float32)
untypedComplex + c64: (2+4i) (type complex64)

2. Mixed Integer Operations:
i8 + i16: 1064 (type int16)
i16 + i32: 71000 (type int32)
i32 + i64: 4295037295 (type int64)
u8 + u16: 50200 (type uint16)
u16 + u32: 4000050000 (type uint32)
u32 + u64: 3999999999 (type uint64)
i32 + u32: 4000070000 (type int64)

3. Mixed Float Operations:
f32 + f64: 6.283183 (type float64)
i32 + f64: 70003.141593 (type float64)
u32 + f32: 4000000000.000000 (type float32)

4. Complex Number Operations:
c64 + c128: (2+4i) (type complex128)
f64 + c128: (4.14159265359+2i) (type complex128)
i32 + c64: (70001+2i) (type complex64)
2025/01/15 21:01:00 checkEqual: unexpected output
@cpunion cpunion changed the title Invalid BinOp compilation Wrong BinOp code generation on int/float and untyped Jan 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant