compiler: implement copy directly

The compiler now implements the copy builtin directly instead of calling sliceCopy.
The length is calculated with the llvm.umax.* intrinsics, and the move is performed by llvm.memmove.*.
Both of these operations are easily understood by LLVM's optimization passes.
The type's alignment is also provided to llvm.memmove.*, which is useful when rewriting the move.

Interp no longer needs to reimplement sliceCopy.
Some edge case handling was implemented by sliceCopy but not llvm.memmove.*/llvm.memcpy.*.
I copied this over, so copies of external slices should work now.
Volatile moves/copies are now run at runtime by interp.

There is a 4-byte size increase due to some confusing length logic in sendUSBPacket.
I will look at sendUSBPacket in a future PR.
This commit is contained in:
Nia Waldvogel
2025-12-26 19:19:21 -05:00
committed by Nia
parent bc9708f51a
commit a40586d092
17 changed files with 353 additions and 358 deletions
+2 -11
View File
@@ -2,7 +2,6 @@ package interp
import (
"os"
"strconv"
"strings"
"testing"
"time"
@@ -11,25 +10,17 @@ import (
)
func TestInterp(t *testing.T) {
llvmVersion, err := strconv.Atoi(strings.Split(llvm.Version, ".")[0])
if err != nil {
// Note: this should never happen and if it does, it will always happen
// for a particular build because llvm.Version is a constant.
panic(err)
}
for _, name := range []string{
"basic",
"phi",
"slice-copy",
"consteval",
"intrinsics",
"copy",
"interface",
"revert",
"alloc",
} {
name := name // make local to this closure
if name == "slice-copy" && llvmVersion < 14 {
continue
}
t.Run(name, func(t *testing.T) {
t.Parallel()
runTest(t, "testdata/"+name)