mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-15 08:23:41 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c33682cf00 | |||
| 570a3deac2 |
@@ -40,7 +40,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.27.0-rc.3'
|
||||
go-version: '1.27.0-rc.2'
|
||||
cache: true
|
||||
- name: Restore LLVM source cache
|
||||
uses: actions/cache/restore@v5
|
||||
@@ -131,7 +131,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.27.0-rc.3'
|
||||
go-version: '1.27.0-rc.2'
|
||||
cache: true
|
||||
- name: Build TinyGo (LLVM ${{ matrix.version }})
|
||||
run: go install -tags=llvm${{ matrix.version }}
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.27.0-rc.3'
|
||||
go-version: '1.27.0-rc.2'
|
||||
cache: true
|
||||
- name: Run go mod tidy
|
||||
run: go mod tidy
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
# statically linked binary.
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: golang:1.27rc3-alpine
|
||||
image: golang:1.27rc2-alpine
|
||||
outputs:
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
steps:
|
||||
@@ -160,7 +160,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.27.0-rc.3'
|
||||
go-version: '1.27.0-rc.2'
|
||||
cache: true
|
||||
- name: Install wasmtime
|
||||
uses: bytecodealliance/actions/wasmtime/setup@v1
|
||||
@@ -204,7 +204,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.27.0-rc.3'
|
||||
go-version: '1.27.0-rc.2'
|
||||
cache: true
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v6
|
||||
@@ -323,7 +323,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.27.0-rc.3'
|
||||
go-version: '1.27.0-rc.2'
|
||||
cache: true
|
||||
- name: Restore LLVM source cache
|
||||
uses: actions/cache/restore@v5
|
||||
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.27.0-rc.3'
|
||||
go-version: '1.27.0-rc.2'
|
||||
cache: true
|
||||
- name: Restore cached LLVM source
|
||||
uses: actions/cache/restore@v5
|
||||
@@ -129,7 +129,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.27.0-rc.3'
|
||||
go-version: '1.27.0-rc.2'
|
||||
cache: true
|
||||
- name: Download TinyGo build
|
||||
uses: actions/download-artifact@v8
|
||||
@@ -150,7 +150,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.27.0-rc.3'
|
||||
go-version: '1.27.0-rc.2'
|
||||
cache: true
|
||||
- name: Download TinyGo build
|
||||
uses: actions/download-artifact@v8
|
||||
@@ -176,7 +176,7 @@ jobs:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.27.0-rc.3'
|
||||
go-version: '1.27.0-rc.2'
|
||||
cache: true
|
||||
- name: Download TinyGo build
|
||||
uses: actions/download-artifact@v8
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
# tinygo-llvm stage obtains the llvm source for TinyGo
|
||||
FROM golang:1.27rc3 AS tinygo-llvm
|
||||
FROM golang:1.27rc2 AS tinygo-llvm
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y apt-utils make cmake clang-17 ninja-build && \
|
||||
@@ -33,7 +33,7 @@ RUN cd /tinygo/ && \
|
||||
|
||||
# tinygo-compiler copies the compiler build over to a base Go container (without
|
||||
# all the build tools etc).
|
||||
FROM golang:1.27rc3 AS tinygo-compiler
|
||||
FROM golang:1.27rc2 AS tinygo-compiler
|
||||
|
||||
# Copy tinygo build.
|
||||
COPY --from=tinygo-compiler-build /tinygo/build/release/tinygo /tinygo
|
||||
|
||||
+9
-2
@@ -24,6 +24,7 @@ import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/gofrs/flock"
|
||||
"github.com/tinygo-org/tinygo/compileopts"
|
||||
@@ -269,6 +270,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
// Create the *ssa.Program. This does not yet build the entire SSA of the
|
||||
// program so it's pretty fast and doesn't need to be parallelized.
|
||||
program := lprogram.LoadSSA()
|
||||
buildProgram := sync.OnceFunc(program.Build)
|
||||
|
||||
// Add jobs to compile each package.
|
||||
// Packages that have a cache hit will not be compiled again.
|
||||
@@ -398,8 +400,13 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
return nil
|
||||
}
|
||||
|
||||
// Compile AST to IR. The compiler.CompilePackage function will
|
||||
// build the SSA as needed.
|
||||
// SSA package builds may run concurrently, but the resulting
|
||||
// functions cannot be inspected until all builds have finished:
|
||||
// generic instances and wrappers can be shared across packages.
|
||||
// Build the whole program once before compiling any package.
|
||||
buildProgram()
|
||||
|
||||
// Compile AST to IR.
|
||||
mod, errs := compiler.CompilePackage(pkg.ImportPath, pkg, program.Package(pkg.Pkg), machine, compilerConfig, config.DumpSSA())
|
||||
defer mod.Context().Dispose()
|
||||
defer mod.Dispose()
|
||||
|
||||
@@ -296,6 +296,9 @@ func Sizes(machine llvm.TargetMachine) types.Sizes {
|
||||
}
|
||||
|
||||
// CompilePackage compiles a single package to a LLVM module.
|
||||
//
|
||||
// The SSA package must already be built. When packages are compiled
|
||||
// concurrently, the entire SSA program must be built before compilation starts.
|
||||
func CompilePackage(moduleName string, pkg *loader.Package, ssaPkg *ssa.Package, machine llvm.TargetMachine, config *Config, dumpSSA bool) (llvm.Module, []error) {
|
||||
c := newCompilerContext(moduleName, machine, config, dumpSSA)
|
||||
defer c.dispose()
|
||||
@@ -306,9 +309,6 @@ func CompilePackage(moduleName string, pkg *loader.Package, ssaPkg *ssa.Package,
|
||||
c.runtimePkg = ssaPkg.Prog.ImportedPackage("runtime").Pkg
|
||||
c.program = ssaPkg.Prog
|
||||
|
||||
// Convert AST to SSA.
|
||||
ssaPkg.Build()
|
||||
|
||||
// Assign names to function-local named types before compiling the
|
||||
// package, so that types declared in different functions (or in
|
||||
// different instantiations of a generic function) do not collide.
|
||||
|
||||
@@ -115,7 +115,7 @@ func TestCompiler(t *testing.T) {
|
||||
|
||||
// Update test if needed. Do not check the result.
|
||||
if *flagUpdate {
|
||||
err := os.WriteFile(outPath, []byte(mod.String()), 0666)
|
||||
err := os.WriteFile(outPath, []byte(normalizeIR(mod.String())), 0666)
|
||||
if err != nil {
|
||||
t.Error("failed to write updated output file:", err)
|
||||
}
|
||||
@@ -174,9 +174,8 @@ func TestOptimizedLargeAggregateABI(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// normalizeIR canonicalizes LLVM IR so a single golden file keeps matching
|
||||
// across LLVM versions. Golden files are written against LLVM <21; newer LLVM
|
||||
// prints some attributes differently.
|
||||
// normalizeIR canonicalizes LLVM-version-specific IR spellings for comparison
|
||||
// and when regenerating golden files.
|
||||
func normalizeIR(s string) string {
|
||||
// Golden files are written using the pre-LLVM21 'nocapture' spelling,
|
||||
// which LLVM printed before any co-occurring attribute such as
|
||||
@@ -414,5 +413,7 @@ func testCompilePackage(t *testing.T, options *compileopts.Options, file string)
|
||||
// Compile AST to IR.
|
||||
program := lprogram.LoadSSA()
|
||||
pkg := lprogram.MainPkg()
|
||||
return CompilePackage(file, pkg, program.Package(pkg.Pkg), machine, compilerConfig, false)
|
||||
ssaPkg := program.Package(pkg.Pkg)
|
||||
ssaPkg.Build()
|
||||
return CompilePackage(file, pkg, ssaPkg, machine, compilerConfig, false)
|
||||
}
|
||||
|
||||
Vendored
+16
-16
@@ -19,33 +19,33 @@ define hidden void @main.chanIntSend(ptr dereferenceable_or_null(36) %ch, ptr %c
|
||||
entry:
|
||||
%chan.op = alloca %runtime.channelOp, align 8
|
||||
%chan.value = alloca i32, align 4
|
||||
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %chan.value)
|
||||
call void @llvm.lifetime.start.p0(ptr nonnull %chan.value)
|
||||
store i32 3, ptr %chan.value, align 4
|
||||
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %chan.op)
|
||||
call void @llvm.lifetime.start.p0(ptr nonnull %chan.op)
|
||||
call void @runtime.chanSend(ptr %ch, ptr nonnull %chan.value, ptr nonnull %chan.op, ptr undef) #3
|
||||
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %chan.op)
|
||||
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %chan.value)
|
||||
call void @llvm.lifetime.end.p0(ptr nonnull %chan.op)
|
||||
call void @llvm.lifetime.end.p0(ptr nonnull %chan.value)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
|
||||
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #2
|
||||
declare void @llvm.lifetime.start.p0(ptr nocapture) #2
|
||||
|
||||
declare void @runtime.chanSend(ptr dereferenceable_or_null(36), ptr, ptr dereferenceable_or_null(16), ptr) #0
|
||||
|
||||
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
|
||||
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #2
|
||||
declare void @llvm.lifetime.end.p0(ptr nocapture) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.chanIntRecv(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%chan.op = alloca %runtime.channelOp, align 8
|
||||
%chan.value = alloca i32, align 4
|
||||
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %chan.value)
|
||||
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %chan.op)
|
||||
call void @llvm.lifetime.start.p0(ptr nonnull %chan.value)
|
||||
call void @llvm.lifetime.start.p0(ptr nonnull %chan.op)
|
||||
%0 = call i1 @runtime.chanRecv(ptr %ch, ptr nonnull %chan.value, ptr nonnull %chan.op, ptr undef) #3
|
||||
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %chan.value)
|
||||
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %chan.op)
|
||||
call void @llvm.lifetime.end.p0(ptr nonnull %chan.value)
|
||||
call void @llvm.lifetime.end.p0(ptr nonnull %chan.op)
|
||||
ret void
|
||||
}
|
||||
|
||||
@@ -55,9 +55,9 @@ declare i1 @runtime.chanRecv(ptr dereferenceable_or_null(36), ptr, ptr dereferen
|
||||
define hidden void @main.chanZeroSend(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%chan.op = alloca %runtime.channelOp, align 8
|
||||
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %chan.op)
|
||||
call void @llvm.lifetime.start.p0(ptr nonnull %chan.op)
|
||||
call void @runtime.chanSend(ptr %ch, ptr null, ptr nonnull %chan.op, ptr undef) #3
|
||||
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %chan.op)
|
||||
call void @llvm.lifetime.end.p0(ptr nonnull %chan.op)
|
||||
ret void
|
||||
}
|
||||
|
||||
@@ -65,9 +65,9 @@ entry:
|
||||
define hidden void @main.chanZeroRecv(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #1 {
|
||||
entry:
|
||||
%chan.op = alloca %runtime.channelOp, align 8
|
||||
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %chan.op)
|
||||
call void @llvm.lifetime.start.p0(ptr nonnull %chan.op)
|
||||
%0 = call i1 @runtime.chanRecv(ptr %ch, ptr null, ptr nonnull %chan.op, ptr undef) #3
|
||||
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %chan.op)
|
||||
call void @llvm.lifetime.end.p0(ptr nonnull %chan.op)
|
||||
ret void
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ entry:
|
||||
%select.states.alloca = alloca [2 x %runtime.chanSelectState], align 8
|
||||
%select.send.value = alloca i32, align 4
|
||||
store i32 1, ptr %select.send.value, align 4
|
||||
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %select.states.alloca)
|
||||
call void @llvm.lifetime.start.p0(ptr nonnull %select.states.alloca)
|
||||
store ptr %ch1, ptr %select.states.alloca, align 4
|
||||
%select.states.alloca.repack1 = getelementptr inbounds nuw i8, ptr %select.states.alloca, i32 4
|
||||
store ptr %select.send.value, ptr %select.states.alloca.repack1, align 4
|
||||
@@ -86,7 +86,7 @@ entry:
|
||||
%.repack3 = getelementptr inbounds nuw i8, ptr %select.states.alloca, i32 12
|
||||
store ptr null, ptr %.repack3, align 4
|
||||
%select.result = call { i32, i1 } @runtime.chanSelect(ptr undef, ptr nonnull %select.states.alloca, i32 2, i32 2, ptr null, i32 0, i32 0, ptr undef) #3
|
||||
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %select.states.alloca)
|
||||
call void @llvm.lifetime.end.p0(ptr nonnull %select.states.alloca)
|
||||
%1 = extractvalue { i32, i1 } %select.result, 0
|
||||
%2 = icmp eq i32 %1, 0
|
||||
br i1 %2, label %select.done, label %select.next
|
||||
|
||||
Vendored
+5
-5
@@ -15,7 +15,7 @@ target triple = "wasm32-unknown-wasi"
|
||||
@"reflect/types.type:basic:string" = linkonce_odr constant { i8, ptr } { i8 81, ptr @"reflect/types.type:pointer:basic:string" }, align 4
|
||||
@"reflect/types.type:pointer:basic:string" = linkonce_odr constant { i8, i16, ptr } { i8 -43, i16 0, ptr @"reflect/types.type:basic:string" }, align 4
|
||||
|
||||
declare void @runtime.trackPointer(ptr readonly captures(none), ptr, ptr) #0
|
||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||
@@ -31,7 +31,7 @@ entry:
|
||||
}
|
||||
|
||||
; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
|
||||
declare void @llvm.memcpy.p0.p0.i32(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i32, i1 immarg) #2
|
||||
declare void @llvm.memcpy.p0.p0.i32(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i32, i1 immarg) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8 @"(main.largeReceiver).readLargeValue"(ptr readonly dereferenceable_or_null(1025) %receiver, ptr readonly dereferenceable_or_null(1025) %value, ptr %context) unnamed_addr #1 {
|
||||
@@ -344,7 +344,7 @@ if.then: ; preds = %typeassert.next
|
||||
declare i1 @runtime.typeAssert(ptr, ptr dereferenceable_or_null(1), ptr) #0
|
||||
|
||||
; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: write)
|
||||
declare void @llvm.memset.p0.i32(ptr writeonly captures(none), i8, i32, i1 immarg) #7
|
||||
declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg) #7
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define hidden i8 @main.useLargeMap(ptr readonly dereferenceable_or_null(1025) %key, ptr readonly dereferenceable_or_null(1025) %value, ptr %context) unnamed_addr #1 {
|
||||
@@ -423,12 +423,12 @@ if.then: ; preds = %entry
|
||||
}
|
||||
|
||||
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
|
||||
declare void @llvm.lifetime.start.p0(ptr captures(none)) #8
|
||||
declare void @llvm.lifetime.start.p0(ptr nocapture) #8
|
||||
|
||||
declare void @runtime.chanSend(ptr dereferenceable_or_null(36), ptr, ptr dereferenceable_or_null(16), ptr) #0
|
||||
|
||||
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
|
||||
declare void @llvm.lifetime.end.p0(ptr captures(none)) #8
|
||||
declare void @llvm.lifetime.end.p0(ptr nocapture) #8
|
||||
|
||||
declare i1 @runtime.chanRecv(ptr dereferenceable_or_null(36), ptr, ptr dereferenceable_or_null(16), ptr) #0
|
||||
|
||||
|
||||
Vendored
+18
-18
@@ -21,23 +21,23 @@ entry:
|
||||
%0 = insertvalue %main.hasPadding zeroinitializer, i1 %s.b1, 0
|
||||
%1 = insertvalue %main.hasPadding %0, i32 %s.i, 1
|
||||
%2 = insertvalue %main.hasPadding %1, i1 %s.b2, 2
|
||||
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %hashmap.value)
|
||||
call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %hashmap.key)
|
||||
call void @llvm.lifetime.start.p0(ptr nonnull %hashmap.value)
|
||||
call void @llvm.lifetime.start.p0(ptr nonnull %hashmap.key)
|
||||
store %main.hasPadding %2, ptr %hashmap.key, align 4
|
||||
%3 = call i1 @runtime.hashmapGenericGet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, i32 4, ptr undef) #4
|
||||
call void @llvm.lifetime.end.p0(i64 12, ptr nonnull %hashmap.key)
|
||||
call void @llvm.lifetime.end.p0(ptr nonnull %hashmap.key)
|
||||
%4 = load i32, ptr %hashmap.value, align 4
|
||||
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %hashmap.value)
|
||||
call void @llvm.lifetime.end.p0(ptr nonnull %hashmap.value)
|
||||
ret i32 %4
|
||||
}
|
||||
|
||||
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
|
||||
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #3
|
||||
declare void @llvm.lifetime.start.p0(ptr nocapture) #3
|
||||
|
||||
declare i1 @runtime.hashmapGenericGet(ptr dereferenceable_or_null(48), ptr nocapture, ptr nocapture, i32, ptr) #0
|
||||
|
||||
; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
|
||||
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #3
|
||||
declare void @llvm.lifetime.end.p0(ptr nocapture) #3
|
||||
|
||||
; Function Attrs: noinline nounwind
|
||||
define hidden void @main.testZeroSet(ptr dereferenceable_or_null(48) %m, i1 %s.b1, i32 %s.i, i1 %s.b2, ptr %context) unnamed_addr #2 {
|
||||
@@ -47,13 +47,13 @@ entry:
|
||||
%0 = insertvalue %main.hasPadding zeroinitializer, i1 %s.b1, 0
|
||||
%1 = insertvalue %main.hasPadding %0, i32 %s.i, 1
|
||||
%2 = insertvalue %main.hasPadding %1, i1 %s.b2, 2
|
||||
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %hashmap.value)
|
||||
call void @llvm.lifetime.start.p0(ptr nonnull %hashmap.value)
|
||||
store i32 5, ptr %hashmap.value, align 4
|
||||
call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %hashmap.key)
|
||||
call void @llvm.lifetime.start.p0(ptr nonnull %hashmap.key)
|
||||
store %main.hasPadding %2, ptr %hashmap.key, align 4
|
||||
call void @runtime.hashmapGenericSet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, ptr undef) #4
|
||||
call void @llvm.lifetime.end.p0(i64 12, ptr nonnull %hashmap.key)
|
||||
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %hashmap.value)
|
||||
call void @llvm.lifetime.end.p0(ptr nonnull %hashmap.key)
|
||||
call void @llvm.lifetime.end.p0(ptr nonnull %hashmap.value)
|
||||
ret void
|
||||
}
|
||||
|
||||
@@ -64,17 +64,17 @@ define hidden i32 @main.testZeroArrayGet(ptr dereferenceable_or_null(48) %m, [2
|
||||
entry:
|
||||
%hashmap.key = alloca [2 x %main.hasPadding], align 8
|
||||
%hashmap.value = alloca i32, align 4
|
||||
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %hashmap.value)
|
||||
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %hashmap.key)
|
||||
call void @llvm.lifetime.start.p0(ptr nonnull %hashmap.value)
|
||||
call void @llvm.lifetime.start.p0(ptr nonnull %hashmap.key)
|
||||
%s.elt = extractvalue [2 x %main.hasPadding] %s, 0
|
||||
store %main.hasPadding %s.elt, ptr %hashmap.key, align 4
|
||||
%hashmap.key.repack1 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 12
|
||||
%s.elt2 = extractvalue [2 x %main.hasPadding] %s, 1
|
||||
store %main.hasPadding %s.elt2, ptr %hashmap.key.repack1, align 4
|
||||
%0 = call i1 @runtime.hashmapGenericGet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, i32 4, ptr undef) #4
|
||||
call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %hashmap.key)
|
||||
call void @llvm.lifetime.end.p0(ptr nonnull %hashmap.key)
|
||||
%1 = load i32, ptr %hashmap.value, align 4
|
||||
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %hashmap.value)
|
||||
call void @llvm.lifetime.end.p0(ptr nonnull %hashmap.value)
|
||||
ret i32 %1
|
||||
}
|
||||
|
||||
@@ -83,17 +83,17 @@ define hidden void @main.testZeroArraySet(ptr dereferenceable_or_null(48) %m, [2
|
||||
entry:
|
||||
%hashmap.key = alloca [2 x %main.hasPadding], align 8
|
||||
%hashmap.value = alloca i32, align 4
|
||||
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %hashmap.value)
|
||||
call void @llvm.lifetime.start.p0(ptr nonnull %hashmap.value)
|
||||
store i32 5, ptr %hashmap.value, align 4
|
||||
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %hashmap.key)
|
||||
call void @llvm.lifetime.start.p0(ptr nonnull %hashmap.key)
|
||||
%s.elt = extractvalue [2 x %main.hasPadding] %s, 0
|
||||
store %main.hasPadding %s.elt, ptr %hashmap.key, align 4
|
||||
%hashmap.key.repack1 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 12
|
||||
%s.elt2 = extractvalue [2 x %main.hasPadding] %s, 1
|
||||
store %main.hasPadding %s.elt2, ptr %hashmap.key.repack1, align 4
|
||||
call void @runtime.hashmapGenericSet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, ptr undef) #4
|
||||
call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %hashmap.key)
|
||||
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %hashmap.value)
|
||||
call void @llvm.lifetime.end.p0(ptr nonnull %hashmap.key)
|
||||
call void @llvm.lifetime.end.p0(ptr nonnull %hashmap.value)
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
+29
-24
@@ -76,7 +76,7 @@ func testTransform(t *testing.T, pathPrefix string, transform func(mod llvm.Modu
|
||||
actual = actual[strings.Index(actual, "\ntarget datalayout = ")+1:]
|
||||
|
||||
if *update {
|
||||
err := os.WriteFile(pathPrefix+".out.ll", []byte(actual), 0666)
|
||||
err := os.WriteFile(pathPrefix+".out.ll", []byte(normalizeIR(actual)), 0666)
|
||||
if err != nil {
|
||||
t.Error("failed to write out new output:", err)
|
||||
}
|
||||
@@ -100,28 +100,8 @@ func testTransform(t *testing.T, pathPrefix string, transform func(mod llvm.Modu
|
||||
// equal. That means, only relevant lines are compared (excluding comments
|
||||
// etc.).
|
||||
func fuzzyEqualIR(s1, s2 string) bool {
|
||||
// Golden files are written using the pre-LLVM21 'nocapture' spelling,
|
||||
// which LLVM printed before any co-occurring attribute such as
|
||||
// 'readonly' (e.g. "ptr nocapture readonly"). LLVM 21+ prints the
|
||||
// equivalent 'captures(none)' instead, and after such attributes (e.g.
|
||||
// "ptr readonly captures(none)"). Normalize both name and position back
|
||||
// to the old spelling to keep a single golden file working across LLVM
|
||||
// versions.
|
||||
s1 = normalizeCapturesAttr(s1)
|
||||
s2 = normalizeCapturesAttr(s2)
|
||||
|
||||
// LLVM 21+ also added an explicit 'nocreateundeforpoison' attribute to
|
||||
// certain intrinsic declarations (e.g. llvm.umin) that were implicitly
|
||||
// assumed not to create undef/poison before. It's unrelated to the
|
||||
// escape-analysis behavior under test, so ignore it for comparison.
|
||||
s1 = strings.ReplaceAll(s1, "nocreateundeforpoison ", "")
|
||||
s2 = strings.ReplaceAll(s2, "nocreateundeforpoison ", "")
|
||||
|
||||
// LLVM 22 dropped the (redundant) i64 size argument from
|
||||
// llvm.lifetime.start/end. Normalize away that argument so golden files
|
||||
// written against the two-argument form still match.
|
||||
s1 = lifetimeSizeArgRe.ReplaceAllString(s1, "$1")
|
||||
s2 = lifetimeSizeArgRe.ReplaceAllString(s2, "$1")
|
||||
s1 = normalizeIR(s1)
|
||||
s2 = normalizeIR(s2)
|
||||
|
||||
lines1 := filterIrrelevantIRLines(strings.Split(s1, "\n"))
|
||||
lines2 := filterIrrelevantIRLines(strings.Split(s2, "\n"))
|
||||
@@ -138,6 +118,29 @@ func fuzzyEqualIR(s1, s2 string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func normalizeIR(s string) string {
|
||||
// Golden files are written using the pre-LLVM21 'nocapture' spelling,
|
||||
// which LLVM printed before any co-occurring attribute such as
|
||||
// 'readonly' (e.g. "ptr nocapture readonly"). LLVM 21+ prints the
|
||||
// equivalent 'captures(none)' instead, and after such attributes (e.g.
|
||||
// "ptr readonly captures(none)"). Normalize both name and position back
|
||||
// to the old spelling.
|
||||
s = normalizeCapturesAttr(s)
|
||||
|
||||
// LLVM 21+ also added an explicit 'nocreateundeforpoison' attribute to
|
||||
// certain intrinsic declarations (e.g. llvm.umin) that were implicitly
|
||||
// assumed not to create undef/poison before. It's unrelated to the
|
||||
// escape-analysis behavior under test, so ignore it for comparison.
|
||||
s = strings.ReplaceAll(s, "nocreateundeforpoison ", "")
|
||||
|
||||
// LLVM 22 dropped the (redundant) i64 size argument from
|
||||
// llvm.lifetime.start/end. Normalize away that argument so golden files
|
||||
// written against the two-argument form still match.
|
||||
s = lifetimeSizeArgRe.ReplaceAllString(s, "$1")
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// capturesNoneAttrRe matches a co-occurring attribute directly followed by
|
||||
// 'captures(none)', which is how LLVM 21+ orders these two attributes when
|
||||
// printing IR (the pre-LLVM21 'nocapture' attribute printed the other way
|
||||
@@ -221,7 +224,9 @@ func compileGoFileForTesting(t *testing.T, filename string) llvm.Module {
|
||||
// Compile AST to IR.
|
||||
program := lprogram.LoadSSA()
|
||||
pkg := lprogram.MainPkg()
|
||||
mod, errs := compiler.CompilePackage(filename, pkg, program.Package(pkg.Pkg), machine, compilerConfig, false)
|
||||
ssaPkg := program.Package(pkg.Pkg)
|
||||
ssaPkg.Build()
|
||||
mod, errs := compiler.CompilePackage(filename, pkg, ssaPkg, machine, compilerConfig, false)
|
||||
if errs != nil {
|
||||
for _, err := range errs {
|
||||
t.Error(err)
|
||||
|
||||
Reference in New Issue
Block a user