https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89227
Bug ID: 89227 Summary: gotools test cmd/go fails with link error "call lacks nop, can't restore toc; recompile with -fPIC" Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: go Assignee: ian at airs dot com Reporter: boger at gcc dot gnu.org CC: cmang at google dot com, wschmidt at gcc dot gnu.org Target Milestone: --- Target: ppc64le I'm not sure when this testcase started failing. I can get it to fail consistently if I configure my gccgo build with lto (--enable-languages=c,c++,go,lto). However after searching the gcc-testresults output, it only fails intermittently on those runs, and they don't configure with lto. gotools.log shows this: Running cmd/go cd check-go-dir/src/cmd/go && PATH=/home/boger/gccgo.work/trunk/bld/gotools:/home/boger/golang/base/go/bin:/home/boger/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin GCCGO='/home/boger/gccgo.work/trunk/bld/gotools/check-gccgo' CC='/home/boger/gccgo.work/trunk/bld/gotools/check-gcc' GCCGOTOOLDIR='/home/boger/gccgo.work/trunk/bld/gotools' GO_TESTING_GOTOOLS=yes LD_LIBRARY_PATH=/home/boger/gccgo.work/trunk/bld/powerpc64le-linux/libgo/.libs GOROOT=/home/boger/gccgo.work/trunk/bld/powerpc64le-linux/libgo GOCACHE=/home/boger/gccgo.work/trunk/bld/gotools/gocache-test GOPATH=/home/boger/gccgo.work/trunk/bld/gotools/check-go-dir /home/boger/gccgo.work/trunk/bld/gotools/go test -test.short -test.timeout=600s -test.v # cmd/go.test /home/boger/gccgo.work/trunk/bld/gotools/check-go-dir/src/cmd/go/script_test.go:283: error: call lacks nop, can't restore toc; recompile with -fPIC collect2: error: ld returned 1 exit status FAIL cmd/go [build failed] Here are the steps I use to get down to a compile command to test with: >cd bld/gotools >make check-go-tool This will generate the directories needed for the above command. In order to see everything, you might need to remove directory gocache_test. Submit the above command, adding -x -work before -test.short and direct that into a file like this: cd check-go-dir/src/cmd/go && PATH=/home/boger/gccgo.work/trunk/bld/gotools:/home/boger/golang/base/go/bin:/home/boger/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin GCCGO='/home/boger/gccgo.work/trunk/bld/gotools/check-gccgo' CC='/home/boger/gccgo.work/trunk/bld/gotools/check-gcc' GCCGOTOOLDIR='/home/boger/gccgo.work/trunk/bld/gotools' GO_TESTING_GOTOOLS=yes LD_LIBRARY_PATH=/home/boger/gccgo.work/trunk/bld/powerpc64le-linux/libgo/.libs GOROOT=/home/boger/gccgo.work/trunk/bld/powerpc64le-linux/libgo GOCACHE=/home/boger/gccgo.work/trunk/bld/gotools/gocache-test GOPATH=/home/boger/gccgo.work/trunk/bld/gotools/check-go-dir /home/boger/gccgo.work/trunk/bld/gotools/go test -x -work -test.short -test.timeout=600s -test.v 2> link.out The error message happens because the call to testenv.HasLink does not have a nop following its 'bl' instruction. This call occurs in script_test.go. In the link.out find the value for $WORK and then the compile command that includes script_test.go. I was able to minimize the go files to these, and put the output file into the current directory instead of under $WORK. ../../../../check-gccgo -c -g -fdebug-prefix-map=$WORK=/tmp/go-build -gno-record-gcc-switches -fgo-pkgpath=cmd/go_test -O0 -o _go_.o -I $WORK/b104/_importcfgroot_ ./go_test.go ./proxy_test.go ./script_test.go -v Using the -v output I use this command: /home/boger/gccgo.work/trunk/bld/./gcc/go1 ./go_test.go ./proxy_test.go ./script_test.go -quiet -dumpbase go_test.go -auxbase-strip _go_.o -g -gno-record-gcc-switches -O0 -version -fdebug-prefix-map=/tmp/go-build260802146=/tmp/go-build -fgo-pkgpath=cmd/go_test -I /tmp/go-build260802146/b104/_importcfgroot_ -I /home/boger/gccgo.work/trunk/bld/powerpc64le-linux/libgo -L/home/boger/gccgo.work/trunk/bld/powerpc64le-linux/libgo -L/home/boger/gccgo.work/trunk/bld/powerpc64le-linux/libgo/.libs -L/home/boger/gccgo.work/trunk/bld/./gcc -L/home/boger/gccgo.work/trunk/bld/powerpc64le-linux/libgo/../libstdc++-v3/src/.libs -L/home/boger/gccgo.work/trunk/bld/powerpc64le-linux/libgo/../libstdc++-v3/libsupc++/.libs -L/lib/powerpc64le-linux-gnu -L/lib/../lib64 -L/usr/lib/powerpc64le-linux-gnu -fdump-rtl-expand -o /tmp/ccqwFgbq.s I can see in the asm output file, that there is no nop following the call to HasLink: .LBB2080: .loc 5 283 18 bl internal..z2ftestenv.HasLink .LEHE4985: mr 9,3 But there is one after all other calls in the file including others from testenv. I did an rtl dump too although not sure what this is telling me. The call to HasLink looks like this: (call_insn 1086 1085 1973 191 (parallel [ (set (reg:DI 3 3) (call (mem:SI (symbol_ref:DI ("internal..z2ftestenv.HasLink") [flags 0x3] <function_decl 0x73998cf76d00 testenv.HasLink>) [0 testenv.HasLink S4 A8]) (const_int 0 [0]))) (clobber (reg:DI 65 lr)) ]) "./script_test.go":283:18 -1 (expr_list:REG_EH_REGION (const_int 1 [0x1]) (nil)) (expr_list (use (reg:DI 2 2)) (nil))) (note 1973 1086 1087 192 [bb 192] NOTE_INSN_BASIC_BLOCK) The interesting information here is that the flags on this call are 0x3 but all other calls in the file have flags 0x41. I have not found what the flags mean yet but that looks like it could be the problem.