Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/cmd/compile/internal/ssa/ssa2llvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -1107,6 +1107,8 @@ func (lfc *LLVMFuncContext) GenLV(v *Value) llvm.Value {
lVal = lfc.llvmUnaryFloat64Intrinsic(v, "llvm.sqrt.f64")
case OpAbs:
lVal = lfc.llvmUnaryFloat64Intrinsic(v, "llvm.fabs.f64")
case OpTrunc:
lVal = lfc.llvmUnaryFloat64Intrinsic(v, "llvm.trunc.f64")
case OpEq64, OpEq32, OpEq16, OpEq8, OpEqB:
lVal = lfc.goBool(lfc.b.CreateICmp(llvm.IntEQ, arg0(), arg1(), v.String()+".i1"), v.String())
case OpEqPtr:
Expand Down
17 changes: 17 additions & 0 deletions test/codegen/llvm_trunc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// asmcheck -gcflags=-d=ssa/check/on

// Copyright 2026 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 codegen

import "math"

// LLVM-LABEL: define goabiinternal double @codegen.llvmTrunc64(double %x)
// LLVM: call double @llvm.trunc.f64(double %x)
// LLVM-OPT-LABEL: define goabiinternal double @codegen.llvmTrunc64(double %x)
// LLVM-OPT: call double @llvm.trunc.f64(double %x)
func llvmTrunc64(x float64) float64 {
return math.Trunc(x)
}
26 changes: 26 additions & 0 deletions test/llvm_float_intrinsics.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ func abs64(x float64) float64 {
return math.Abs(x)
}

//go:noinline
func trunc64(x float64) float64 {
return math.Trunc(x)
}

//go:noinline
func round64(x float64) float64 {
return float64(x)
Expand Down Expand Up @@ -55,6 +60,27 @@ func main() {
panic("abs NaN payload")
}

for _, tc := range []struct {
in, want uint64
}{
{0x0000000000000000, 0x0000000000000000}, // +0
{0x8000000000000000, 0x8000000000000000}, // -0
{0x400e000000000000, 0x4008000000000000}, // 3.75 -> 3
{0xc00e000000000000, 0xc008000000000000}, // -3.75 -> -3
{0x0000000000000001, 0x0000000000000000}, // smallest subnormal -> +0
{0x8000000000000001, 0x8000000000000000}, // negative subnormal -> -0
{0x43efffffffffffff, 0x43efffffffffffff}, // largest finite value below 2^64
{0x7ff0000000000000, 0x7ff0000000000000}, // +Inf
{0xfff0000000000000, 0xfff0000000000000}, // -Inf
} {
if got := math.Float64bits(trunc64(math.Float64frombits(tc.in))); got != tc.want {
panic("trunc semantics")
}
}
if !math.IsNaN(trunc64(math.Float64frombits(nanBits))) {
panic("trunc NaN")
}

for _, bits := range []uint64{0, 1 << 63, 0x3ff0000000000000, nanBits} {
if got := math.Float64bits(round64(math.Float64frombits(bits))); got != bits {
panic("float64 rounding identity")
Expand Down
11 changes: 9 additions & 2 deletions test/llvm_tests.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"codegen/llvm_round64.go": "non-contracting Round64F identity on strict LLVM double values",
"codegen/llvm_selectnaddr.go": "caller-owned aligned memory home for address-selected stack call results",
"codegen/llvm_sqrt.go": "float64 square root through the LLVM sqrt intrinsic",
"codegen/llvm_trunc.go": "SSA-verified float64 truncation toward zero through the LLVM trunc intrinsic",
"codegen/llvm_memops.go": "pointer-free zero and overlap-safe move intrinsics, runtime memequal, and native-int slice masks",
"codegen/llvm_memory_order.go": "preserve Go SSA Memory-token order when LLVM emission precedes native scheduling",
"codegen/llvm_newproc.go": "pointer-typed funcval argument for the runtime.newproc raw ABI call",
Expand Down Expand Up @@ -69,7 +70,8 @@
},
"platform_blacklist": {
"linux/amd64": {
"codegen/llvm_abs.go": "the native AMD64 frontend does not form OpAbs for math.Abs"
"codegen/llvm_abs.go": "the native AMD64 frontend does not form OpAbs for math.Abs",
"codegen/llvm_trunc.go": "GOAMD64=v1 guards OpTrunc with unsupported HasCPUFeature lowering"
}
}
},
Expand Down Expand Up @@ -258,6 +260,7 @@
"fixedbugs/issue57309.go": "upstream regression repeatedly qualified through LLVM compile, link, and execution",
"fixedbugs/issue64565.go": "upstream regression repeatedly qualified through LLVM compile, link, and execution",
"fixedbugs/issue66585.go": "upstream regression repeatedly qualified through LLVM compile, link, and execution",
"fixedbugs/issue68322.go": "large float64 truncation above the signed integer range through LLVM compile, link, and execution",
"fixedbugs/issue68415.go": "upstream regression repeatedly qualified through LLVM compile, link, and execution",
"fixedbugs/issue68525.go": "upstream regression repeatedly qualified through LLVM compile, link, and execution",
"fixedbugs/issue68809.go": "upstream regression repeatedly qualified through LLVM compile, link, and execution",
Expand Down Expand Up @@ -422,6 +425,10 @@
"blacklist": {
"*": "LLVM lowering or runtime ABI support has not reached this test yet"
},
"platform_blacklist": {}
"platform_blacklist": {
"linux/amd64": {
"fixedbugs/issue68322.go": "GOAMD64=v1 guards OpTrunc with unsupported HasCPUFeature lowering"
}
}
}
}