How to build gollvm on arm platform

640 views
Skip to first unread message

morefu...@gmail.com

unread,
Dec 10, 2018, 12:54:05 PM12/10/18
to golang-nuts
 I try to compile gollvm on arm platform according to https://go.googlesource.com/gollvm/, but error is reported as following

CMake Error at tools/gollvm/cmake/modules/GoVars.cmake:12 (message):
  Arch aarch64 not yet supported

https://go.googlesource.com/gollvm/ tells that Gollvm is currently supported only for x86_64 Linux.

Is there any way to compile gollvm on arm platform?

Thanks

Than McIntosh

unread,
Dec 10, 2018, 1:46:47 PM12/10/18
to morefu...@gmail.com, golang-nuts
Hello,

As things stand, gollvm isn't usable for Arm (32 or 64); the cmake error you are hitting is intentional.

The main obstacle for enabling Arm is enhancing the Gollvm bridge to support the Arm ABI, e.g. the rules for passing parameters (in memory vs register) depending on the signature of the called routine.  Adding ARM support is something that's on the Gollvm "to do" list, but hasn't reached the top. Once the ABI support is there it should not be a lot of additional work.

If you are interested in contributing code to help fix the problem, we can point you in the right direction and provide guidance, but it will take a bit of doing.

Thanks, Than


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

morefu...@gmail.com

unread,
Dec 10, 2018, 9:52:32 PM12/10/18
to golang-nuts

@Than, Thank you for your detailed answer.

I am interested in contributing code to enable ARM port. I plan to spend some times on learning gofrontend firstly, then the bridge. What I want to learn about are

1, Is there any arch-specific code/IR in gofrontend?
2, What's the missing to support ARM ABI in gollvm bridge, anything else besides of passing parameters?
3, What can we do on runtime for arm?
4, How to test what we do on arm without building support?

I would be appreciated if you can give me suggestion and guidance.

Thanks


在 2018年12月11日星期二 UTC+8上午2:46:47,Than McIntosh写道:

Than McIntosh

unread,
Dec 11, 2018, 11:30:18 AM12/11/18
to morefu...@gmail.com, golang-nuts
Hi again,

>>I am interested in contributing code to enable ARM port. I plan to spend some times on learning gofrontend firstly, then the bridge.

That sounds great.  I can certainly offer advice and help along the way.

>>1, Is there any arch-specific code/IR in gofrontend?

The frontend code (e.g. the "go" subdir in the gofrontend repo) doesn't have anything architecture-specific as far as I know (Ian can correct me if I am wrong here). The gofrontend repo also has a "libgo" subdirectory containing the Go runtime and standard packages, and there are obviously arch-specific portions there (both in Go code and C code).

2, What's the missing to support ARM ABI in gollvm bridge, anything else besides of passing parameters?

In the gollvm 'bridge' subdirectory there is a C++ class CABIOracle; this is the class that you'll need to focus on. The model we're using is that when other parts of the bridge need to ask ABI-related questions about a function call, they create a CABIOracle object (passing the oracle type information about the call), then invoke various methods to get info on how parameters are passed, etc.

At the moment there is only a single CABIOracle (since we support a single target); it probably makes sense to create subclasses for each target of interest. You'll need to read up on the aarch64 calling convention (especially section 5 of the ARM doc) and write new sets of rules to use.There is also a set of stand-alone unit tests for the CABIOracle class, which is probably a good place to start looking at it.  I'll write down a more specific list of tips and pointers to the code later today; stay tuned. 

>>3, What can we do on runtime for arm?

The libgo runtime already has ARM linux support that is in use for gccgo, so in theory you should be able to use what's already there.

Cheers, Than

morefu...@gmail.com

unread,
Dec 11, 2018, 10:14:29 PM12/11/18
to golang-nuts
Hi Than,

I will start with CABIOracle as your suggestion. Thanks again. :)

BR.

eric fang

unread,
Jun 25, 2019, 11:41:47 AM6/25/19
to golang-nuts
>>I'll write down a more specific list of tips and pointers to the code later today; stay tuned. 

Hi Than, I'm also very interested in this work and look forward to your update.

 I'm reading the gollvm code, but I haven't figured out the relationship between the various modules (llvm, gofrontend, libbacktrace, libffi ... ) , and the direction of the data flow and control flow. I was also confused by cmake.
Could you give me a general introduction about how gollvm combines these components and compile, assemble, and link go source files as an executable ? I think this will help me have a holistic understanding of the entire gollm project. Thanks !

In the process of looking at the code, I found that I spent a lot of time in the gofrontend project. For enabling arm64, is there some work to do in this sub-project?

Ian Lance Taylor

unread,
Jun 25, 2019, 1:46:29 PM6/25/19
to eric fang, golang-nuts, Than McIntosh
I'm not aware of any changes required to the gofrontend code for arm64
support. I also would not be very surprised if a few changes were
required.

Ian

Than McIntosh

unread,
Jun 27, 2019, 2:00:26 PM6/27/19
to eric fang, golang-nuts

Hello,

For cmake I'd recommend looking at the https://cmake.org/ documentation -- that should give you an overview. We're using cmake with Gollvm since it's the system used by LLVM.  If you aren't familiar with building and testing LLVM, that's a good place to start reading, since gollvm is intended to use the same infrastructure.

In terms of the plumbing and the data flow, let's say that gollvm is compiling a package "xyz" with two Go source files "xyz.go" and "xyzconst.go". The sequence of events looks like the following (on the left is the action taking place, on the right is the location of the code doing the action, and time increases as you move down the page)

          +----------------------------------+
          | code: llvm/tools/gollvm/driver   |
          |                                  |
          | actions:                         |
          | parse command line options       |
          | locate input files               |
          | general setup                    |
          +----------------------------------+
                         |
                         | list of files to parse
                         | xyz.go xyzconst.go
                         V
          +------------------------------------+
          | code: llvm/tools/gollvm/gofrontend |
          |                                    |
          | actions:                           |
          | parsing, type checking, lowering   |
          | escape analysis, etc               |
          |                                    |
          +------------------------------------+
                         |
                         | sequence of calls
                         | into Backend interface
                         V
          +------------------------------------+
          | code: llvm/tools/gollvm/bridge     |
          |                                    |
          | actions:                           |
          | receive Backend calls and          |
          | generate LLVM IR to implement them |
          |                                    |
          +------------------------------------+
                         |
                         | LLVM IR for xyz package
                         V
          +----------------------------------+
          | code: llvm/tools/gollvm/driver   |
          |                                  |
          | actions:                         |
          | setup LLVM pass pipeline         |
          | kick off LLVM backend            |
          +----------------------------------+
                         |
                         | assembly source
                         V
                       assembler
                       produces xyz.o object file
                       

Hope this helps. A lot of the other things in the gollvm source tree are built for use in the Go runtime and standard packages. This includes things in llvm/tools/gollvm/gofrontend/libgo, as well as libffi and libbacktrace.

Hope this helps. If you have specific questions I can try to offer more focused explanations.

Than


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

eric fang

unread,
Jun 28, 2019, 2:52:23 AM6/28/19
to golang-nuts
Hi Than, 
Thanks for your guide, this certainly helps.  I don't have any specific questions at the moment. Thanks again.

eric fang

unread,
Jul 9, 2019, 8:13:34 AM7/9/19
to golang-nuts
Hi Than, when I read the code, I found enable_gc_ is false by default, the description of option "-enable-gc=<value>" is "Enable stack map generation". I guess gollvm should have implemented garbage collection. My question are:
1,  what kind of gc does gollvm currently implement, and what is the difference between this gc and the one in main Go?

2, What effect does this option (-enable-gc) have on gollvm gc?

Thanks!

Than McIntosh

unread,
Jul 9, 2019, 9:15:52 AM7/9/19
to eric fang, golang-nuts
Hi,

This is a good question, and I think it points out that the name of this command line flag ("-enable-gc") is not ideal. It should really be something more like "-enable-precise-stack-scan=<value>".

The garbage collector used by gollvm is substantially the same as the one used by the main Go compiler. The main difference is that by default gollvm uses conservative stack scanning -- chunks of stack memory are scanned assuming that everything that might be a live heap pointer is indeed a live heap pointer. When you build with "-enable-gc=true" it turns on machinery in the compiler to enable precise stack scanning, meaning that the compiler emits stack maps and then the runtime uses those maps to look at only life heap pointers during scanning.

There are some other small differences between Gollvm and GC garbage collection (notably the representation of the global roots list) but in general they are using pretty much the same collector.

Thanks, Than



--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

eric fang

unread,
Jul 9, 2019, 10:39:14 PM7/9/19
to golang-nuts
Thank you for your answer, this makes sense.

在 2019年7月9日星期二 UTC+8下午9:15:52,Than McIntosh写道:
Hi,

This is a good question, and I think it points out that the name of this command line flag ("-enable-gc") is not ideal. It should really be something more like "-enable-precise-stack-scan=<value>".

The garbage collector used by gollvm is substantially the same as the one used by the main Go compiler. The main difference is that by default gollvm uses conservative stack scanning -- chunks of stack memory are scanned assuming that everything that might be a live heap pointer is indeed a live heap pointer. When you build with "-enable-gc=true" it turns on machinery in the compiler to enable precise stack scanning, meaning that the compiler emits stack maps and then the runtime uses those maps to look at only life heap pointers during scanning.

There are some other small differences between Gollvm and GC garbage collection (notably the representation of the global roots list) but in general they are using pretty much the same collector.

Thanks, Than



On Tue, Jul 9, 2019 at 8:13 AM eric fang <fangshu...@gmail.com> wrote:
Hi Than, when I read the code, I found enable_gc_ is false by default, the description of option "-enable-gc=<value>" is "Enable stack map generation". I guess gollvm should have implemented garbage collection. My question are:
1,  what kind of gc does gollvm currently implement, and what is the difference between this gc and the one in main Go?

2, What effect does this option (-enable-gc) have on gollvm gc?

Thanks!

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golan...@googlegroups.com.

eric fang

unread,
Jul 15, 2019, 5:52:39 AM7/15/19
to golang-nuts
Hi,

Another three questions about test and benchmark.

1, Currently I can build all unit test executable files by "% ninja GoBackendUnitTests", but in order to run all tests, I have to run the  test executable files under all the directories. Do we have a single command to perform all unit tests?

2, How to perform unit tests of std libraries with the "go" binary ? For example, in main Go, we can perform unit tests in src/bytes package with command "% go test -run . bytes", in gollvm, can we do the same thing?

3, How to perform benchmark tests of std libraries ? Can I perform a benchmark test of std bytes package by executing "% go test -bench . bytes" command somewhere ?

Thanks.

Than McIntosh

unread,
Jul 15, 2019, 3:41:19 PM7/15/19
to eric fang, golang-nuts
Hi,

>>  Currently I can build all unit test executable files by "% ninja GoBackendUnitTests", but in order to run all tests, I have to run the  test executable files under all the directories. Do we have a single command to perform all unit tests?

Such a target doesn't exist yet -- I agree that it would be useful, and at one point I made an attempt to add it, but didn't finish.  I've looked at the similar code in the LLVM cmake sources and found it a bit complicated, hence my hesitation. 

>> How to perform unit tests of std libraries with the "go" binary ? For example, in main Go, we can perform unit tests in src/bytes package with command "% go test -run . bytes", in gollvm, can we do the same thing?

Here we do have a target: "check-gollm". That will run the package tests as you describe above, plus the gotools tests. 

>> How to perform benchmark tests of std libraries ? Can I perform a benchmark test of std bytes package by executing "% go test -bench . bytes" command somewhere ?

"Go test -bench" will certainly work, although at the moment I'm not sure we have any wrappers/tooling-- I'd recommend giving it a try to see what happens.

You can also run the regular "go1" benchmarks as well, we do that on a regular basis when looking at gollvm improvements.

Thanks, Than



--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

eric fang

unread,
Jul 17, 2019, 4:23:55 AM7/17/19
to golang-nuts
Hi Than,

Thanks for your help, "check-gollvm" is exactly what I'm looking for. But on x86-64, there are two test failures, as the log is very long, we just put some key info here.
[152/189] Checking Go package go/internal/gccgoimporter
FAILED: tools/gollvm/libgo/CMakeFiles/check_libgo_go_internal_gccgoimporter
--- FAIL: TestObjImporter (0.08s)
    importer_test.go:134: could not find version number in gollvm version 1 (experimental) [LLVM version 9]
FAIL
[189/189] Checking cmd/go tool
FAILED: tools/gollvm/gotools/CMakeFiles/check_go_tool
(see the attached log file)

I still don't know how to run the benchmark tests in the standard library and "go1" benchmarks, can you give me more details, thanks.
I didn't find a cmake target for benchmark tests, and I tried the following commands but not work:
$ go version
go version go1.12.2 gollvm LLVM 9.0.0svn linux/amd64
$ cd gollvm-workarea/llvm/tools/gollvm/gofrontend/libgo/go/bytes
$ go test -bench . 
bytes.go:10:2: use of internal package internal/bytealg not allowed
cmd_go-testlog

Than McIntosh

unread,
Jul 17, 2019, 8:51:07 AM7/17/19
to eric fang, golang-nuts
Hi,

These are both known failures at the moment -- 

The gccgo importer test was is sensitive to the version of gccgo being used (it runs gccgo on Go source code, and needs to test the gccgo version to see whether it is sufficiently new to support constructs like aliases). The test doesn't yet support checking for gollvm versions, partly because we don't really have a gollvm version scheme yet.  

The cmd/go test failure is a timeout -- this test runs for a long time and tends to time out occasionally (particularly with debug builds).

Than
 


The cmd/go test is timing out -- this is a test that runs for a loing 

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

eric fang

unread,
Aug 20, 2019, 8:42:33 AM8/20/19
to golang-nuts
Hi Than,

I'm trying to implement the abi part for arm64, and got two questions for you:

1, function CABIOracle::canPassDirectly in gollvm/bridge/go-llvm-cabi-oracle.cpp, I'm not quite understand the first if statement:
  if (regsInt + regsSSE == 1)
   return true;
  Why not consider whether there are enough available registers here?

2, I plan to abstract the CABIOracle class into a base class, and each architecture implements an inheritance class based on this class. But there are some auxiliary classes and structures (like class CABIParamInfo and EightByteInfo etc.) in this file that are also x86 specific. I haven't figured out how to handle these yet, maybe some of them are also reusable. Do you think this design is reasonable? Any suggestions? I should submit a prototype patch, which would be more convenient to discuss, but I have not implemented it yet. . .

Than McIntosh

unread,
Aug 20, 2019, 9:33:56 AM8/20/19
to eric fang, golang-nuts, Cherry Zhang
Hi Eric,

Thanks for the note. Your question about the code in CABIOracle::canPassDirectly, e.g .

  if (regsInt + regsSSE == 1)
    return true;

is a good one.  I'll see about adding some comments to the code there. 

By way of explanation, the Gollvm code is modeled after the approach used in clang, which does something similar in this case. For example, consider the following small C program:

typedef unsigned long long u;
extern u bar(u p1, u p2, u p3, u p4, u p5, u p6, u p7, u p8, u p9, u p10);
u foo(u p) {
  return bar(1,2,3,4,5,6,7,8,9,p);
}

Let's say you compile this code with clang for x86_64 and look at the emitted LLVM IR and emitted assembly, e.g. 

clang -c -S file.c -O 
clang -c -S file.c -O -emit-llvm

In the *.ll file you'll see this LLVM IR for 'foo':

define i64 @foo(i64) local_unnamed_addr #0 {
  %2 = tail call i64 @bar(i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 %0) #2
  ret i64 %2
}

What is interesting here is that the function being called, "bar", has 7 arguments. Under the rules of the C/C++ ABI for x86_64, not all of the parameters can be passed in registers -- some of them have to go in memory. However looking at the signature, there are no memory arguments, everything is being passed by value. Now let's look at the assembly:

foo:    
pushq %rax
movq %rdi, (%rsp)
movl $1, %edi
movl $2, %esi
movl $3, %edx
movl $4, %ecx
movl $5, %r8d
movl $6, %r9d
callq bar
popq %rcx
retq

As you can see, the back end knows about the rules of the C/C++ ABI for x86_64, and it has put the right things in registers and in memory so that the ABI is honored.

So essentially what's happening is that the front end (clang) is playing a little game with the back end -- for the more complicated cases involving aggregates and things bigger than a single register, the front end makes the LLVM IR explicit with regard to what gets passed in memory via by value. For small parameters (things that will fit into a single register) it just leaves them by value and counts on having the back end sort it out. Doing things this way has advantages from a performance perspective.

For your second question, yes, your approach seems reasonable -- making CABIOracle into a base class and then adding virtual methods seems like the right way to go. I don't have any very specific advice on classes like CABIParamInfo and EightByteInfo -- I would say the former seems a bit more abstract and reusable whereas the notion of an "EightByte" seems pretty specific to the language in the x86_64 abi description. I would just take your best shot and see how things go. 

Hope this helps, let me know if you have other questions...

Thanks, Than


 

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

Than McIntosh

unread,
Aug 20, 2019, 9:41:27 AM8/20/19
to eric fang, golang-nuts, Cherry Zhang
Forgot to add:

When I was writing the x86_64 ABI code for gollvm, I spent some time creating an ABI test harness to find problems in my code. You can find it at:


The overall idea is that it randomly generates a lot of parameter-passing code, then you can build half of the code with a "known good" compiler (in this case gccgo would be the logical choice) and then the other half with the compiler you are developing.  This may be useful once you get a bit farther along.

Cheers, Than

Than McIntosh

unread,
Aug 20, 2019, 10:25:38 AM8/20/19
to eric fang, golang-nuts, Cherry Zhang
Thanks, Than


On Tue, Aug 20, 2019 at 9:33 AM Than McIntosh <th...@google.com> wrote:

eric fang

unread,
Aug 20, 2019, 9:51:45 PM8/20/19
to golang-nuts
Hi Than,

I got it, thanks for your detailed explanation. And I'm also thinking about how to write test cases, the cabi-testgen project would be a great help, I will keep you informed if there are other questions or updates, thank you.

eric fang

unread,
Sep 17, 2019, 9:30:57 AM9/17/19
to golang-nuts
Hi Than,

I got another question for you. For indirect parameters, arm-aapcs abi requires to do a copy of the parameter on stack, and then pass the address  of the copied parameter to callee. I tried to do a memcpy of the indirect parameter in function Llvm_backend::genCallMarshallArgs, but failed to build. The code are as follow:

git diff
diff --git a/bridge/go-llvm-materialize.cpp b/bridge/go-llvm-materialize.cpp
index 3985153..bc8c147 100644
--- a/bridge/go-llvm-materialize.cpp
+++ b/bridge/go-llvm-materialize.cpp
@@ -1194,7 +1194,22 @@ Llvm_backend::genCallMarshallArgs(const std::vector<Bexpression *> &fn_args,
         llvm::Type *pt = llvm::PointerType::get(vt->getPointerElementType(), 0);
         val = builder.CreateAddrSpaceCast(val, pt, castname);
       }
-      state.llargs.push_back(val);
+
+//      BlockLIRBuilder bbuilder(state.callerFcn->function(), this);
+      TypeManager *tm = state.oracle->tm();
+      Btype *bty = fnarg->btype();
+      uint64_t sz = tm->typeSize(bty);
+      uint64_t algn = tm->typeAlignment(bty);
+      std::string tname(namegen("arm64indtpara.actual"));
+      llvm::Value *tmpV = state.callerFcn->createTemporary(bty, tname);
+      llvm::CallInst *cpyVal = builder.CreateMemCpy(tmpV, algn, val, algn, sz);
+      state.llargs.push_back(cpyVal);
+//      llvm::CallInst *cpyVal = builder.CreateMemCpy(tmpV, algn, val, algn, sz);
+//           std::vector<llvm::Instruction *> instructions = bbuilder.instructions();
+//           for (auto i : instructions)
+//             state.llargs.push_back(i);
+
+//      state.llargs.push_back(val);
       continue;
     }

Any suggestions on how and where to implement this situation? I found that here we need to know a little bit about the LLVM backend, but I almost knew nothing about it.

eric fang

unread,
Sep 18, 2019, 3:46:21 AM9/18/19
to golang-nuts
Hi Than, I think here should be the right place to handle this case, and I have corrected the code. I should use BlockLIRBuilder instead of BinstructionLIRBuilder. I have implemented a prototype of the code and at present everything is normal. Next I will start writing some unit test cases. There are some places that are not easy to extend. For example, in the constructor of class Llvm_backend, calling convention is hard coded, and the unit test needs to get an Llvm_backend instance through the go_get_backend function in the file bridge/go-llvm.cpp. I am thinking about how to deal with this.

Than McIntosh

unread,
Sep 18, 2019, 9:59:44 AM9/18/19
to eric fang, golang-nuts
Thanks for the update. BlockLIRBuilder sounds like the right way to go, and your plan to add unit tests SGTM.

Agree that we'll need to thread through the arch/callingConv into the unit testing framework, let me know if I can help with that.

Cheers, Than





On Wed, Sep 18, 2019 at 3:46 AM eric fang <eric...@arm.com> wrote:
Hi Than, I think here should be the right place to handle this case, and I have corrected the code. I should use BlockLIRBuilder instead of BinstructionLIRBuilder. I have implemented a prototype of the code and at present everything is normal. Next I will start writing some unit test cases. There are some places that are not easy to extend. For example, in the constructor of class Llvm_backend, calling convention is hard coded, and the unit test needs to get an Llvm_backend instance through the go_get_backend function in the file bridge/go-llvm.cpp. I am thinking about how to deal with this.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

joe mcguckin

unread,
Sep 18, 2019, 8:02:09 PM9/18/19
to golang-nuts
What's the difference between the standard GO compiler and GOLLVM? I thought there was an llvm based compiler that was abandoned?

Thanks,

Joe

Ian Lance Taylor

unread,
Sep 18, 2019, 8:08:16 PM9/18/19
to joe mcguckin, golang-nuts
On Wed, Sep 18, 2019 at 5:02 PM joe mcguckin
<joseph.p...@gmail.com> wrote:
>
> What's the difference between the standard GO compiler and GOLLVM?

The standard Go compiler, also called the gc compiler, is written
entirely in Go. GoLLVM is written in C++ and uses the LLVM backend.

> I thought there was an llvm based compiler that was abandoned?

I don't know just how abandoned is, but it's true that there are two
Go compilers based on LLVM: llgo and GoLLVM. GoLLVM is under active
development. I'm not sure what the status of llgo is. llgo uses
standard Go library packages like go/parser and go/types with the LLVM
backend.

Ian

joe mcguckin

unread,
Sep 18, 2019, 10:09:21 PM9/18/19
to golang-nuts
Ian,

What's the advantage of an LLVM based compiler. GC seems to be fast and makes OK code. Is the llvm toolchain that much better?

joe

Ian Lance Taylor

unread,
Sep 19, 2019, 12:32:29 AM9/19/19
to joe mcguckin, golang-nuts
On Wed, Sep 18, 2019 at 7:09 PM joe mcguckin
<joseph.p...@gmail.com> wrote:
>
> What's the advantage of an LLVM based compiler. GC seems to be fast and makes OK code. Is the llvm toolchain that much better?

It's always a good idea to have multiple compilers, as it helps ensure
that the language is defined by a spec rather than an implementation.

And, yes, the LLVM compiler generates code that is clearly better for
some cases, though the compilation process itself is longer.

Ian

eric fang

unread,
Oct 25, 2019, 2:41:25 AM10/25/19
to golang-nuts
Hi Than,

I'm porting the unit test cases of x86 to arm64. As the difference between x86 abi and arm64 abi, for the same go code snippet, the generated llvm IRs maybe different. 
How do you get the correct IR result of a unit test? Such as unit test TEST(BackendCABIOracleTests, RecursiveCall1). Is there any quick way?

Thanks.

Than McIntosh

unread,
Oct 25, 2019, 8:07:55 AM10/25/19
to eric fang, golang-nuts
Hi Eric,

Yes, this is a problem that is pretty much guaranteed to happen given the way the C ABI works in LLVM.  All of the test results in BackendCABIOracleTests.cpp are specific to the details of the amd64 ABI.

The way that I had imagined this working was that either each testpoint has a loop over the various supported ABI flavors (and checks output for each flavor), or we have separate testpoints for each ABI (e.g. TEST(BackendCABIOracleTests, X8664_RecursiveCall1) or equivalent. Or even separate test files, depending on what's more convenient. It would be nice if FcnTestHarness could be extended to accept a "target ABI" parameter, maybe? Whatever you think is the best approach.

Thanks for taking care of this --

Than




--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

eric fang

unread,
Oct 25, 2019, 8:26:39 AM10/25/19
to golang-nuts
The way that I had imagined this working was that either each testpoint has a loop over the various supported ABI flavors (and checks output for each flavor)
Yes, for those common test cases, I just did this.
 
or we have separate testpoints for each ABI (e.g. TEST(BackendCABIOracleTests, X8664_RecursiveCall1) or equivalent.
For those test cases that will generate different results on different platforms, I use this way. 

It would be nice if FcnTestHarness could be extended to accept a "target ABI" parameter
I have done this extention.
 

 I'm porting the unit test cases of x86 to arm64. As the difference between x86 abi and arm64 abi, for the same go code snippet, the generated llvm IRs maybe different. 
How do you get the correct IR result of a unit test? Such as unit test TEST(BackendCABIOracleTests, RecursiveCall1). Is there any quick way?
Maybe I didn't say my question clearly. I want to know how to get the correct LLVM IR result of a piece of go code. Are they handwritten? Is there a simpler way to get it?

Thanks.

local.tou...@gmail.com

unread,
Jul 28, 2020, 10:48:05 PM7/28/20
to golang-nuts
Pre-compiled x86_64 debug and "release" builds are on my way.

Ivan

On Monday, December 10, 2018 at 7:54:05 PM UTC+2, moref...@gmail.com wrote:
 I try to compile gollvm on arm platform according to https://go.googlesource.com/gollvm/, but error is reported as following

CMake Error at tools/gollvm/cmake/modules/GoVars.cmake:12 (message):
  Arch aarch64 not yet supported

https://go.googlesource.com/gollvm/ tells that Gollvm is currently supported only for x86_64 Linux.

Is there any way to compile gollvm on arm platform?

Thanks
Reply all
Reply to author
Forward
0 new messages