Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

riscv64-linux-musl fails to build: cannot link object files with different floating-point ABI #4863

Closed
andrewrk opened this issue Mar 30, 2020 · 6 comments · Fixed by #4923
Closed
Labels
arch-riscv RISCV-32 and RISCV-64
Milestone

Comments

@andrewrk
Copy link
Member

Extracted from #4485. See also #4456.

#include <iostream>

int main(int argc, char **argv) {
    std::cout << "Hello World!" << std::endl;
    return 0;
}
$ ./zig build-exe --c-source hello.cpp -lc++ -lc -target riscv64-linux-musl
lld: error: /home/andy/.cache/zig/stage1/o/rWRKkwM2cJJ4c6gEz91MCtccTwDwRvYtWBCJbHf31wuzT5fYo1koVTUiLWnemlaF/libcompiler_rt.a(/home/andy/.cache/zig/stage1/o/rWRKkwM2cJJ4c6gEz91MCtccTwDwRvYtWBCJbHf31wuzT5fYo1koVTUiLWnemlaF/compiler_rt.o): cannot link object files with different floating-point ABI
@LemonBoy
Copy link
Contributor

Check this out.

@andrewrk
Copy link
Member Author

andrewrk commented Apr 2, 2020

I tried this diff:

diff --git a/src/codegen.cpp b/src/codegen.cpp
index c9e67dcac..b2210ba0c 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -8940,10 +8940,17 @@ static void init(CodeGen *g) {
         fprintf(stderr, "name=%s target_specific_cpu_args=%s\n", buf_ptr(g->root_out_name), target_specific_cpu_args);
         fprintf(stderr, "name=%s target_specific_features=%s\n", buf_ptr(g->root_out_name), target_specific_features);
     }
+
+    // TODO handle float ABI better- it should depend on the ABI portion of std.Target
+    ZigLLVMABIType float_abi = ZigLLVMABITypeDefault;
+    if (g->zig_target->os == OsLinux && target_is_riscv(g->zig_target)) {
+        // RISC-V Linux defaults to ilp32d/lp64d
+        float_abi = ZigLLVMABITypeHard;
+    }
     
     g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str),
             target_specific_cpu_args, target_specific_features, opt_level, reloc_mode,
-            to_llvm_code_model(g), g->function_sections);
+            to_llvm_code_model(g), g->function_sections, float_abi);
 
     g->target_data_ref = LLVMCreateTargetDataLayout(g->target_machine);
 
diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp
index 5569f90cd..e06683ef7 100644
--- a/src/zig_llvm.cpp
+++ b/src/zig_llvm.cpp
@@ -100,7 +100,7 @@ static const bool assertions_on = false;
 
 LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple,
     const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
-    LLVMCodeModel CodeModel, bool function_sections)
+    LLVMCodeModel CodeModel, bool function_sections, ZigLLVMABIType float_abi)
 {
     Optional<Reloc::Model> RM;
     switch (Reloc){
@@ -147,6 +147,17 @@ LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Tri
 
     TargetOptions opt;
     opt.FunctionSections = function_sections;
+    switch (float_abi) {
+        case ZigLLVMABITypeDefault:
+            opt.FloatABIType = FloatABI::Default;
+            break;
+        case ZigLLVMABITypeSoft:
+            opt.FloatABIType = FloatABI::Soft;
+            break;
+        case ZigLLVMABITypeHard:
+            opt.FloatABIType = FloatABI::Hard;
+            break;
+    }
 
     TargetMachine *TM = reinterpret_cast<Target*>(T)->createTargetMachine(Triple, CPU, Features, opt, RM, CM,
             OL, JIT);
diff --git a/src/zig_llvm.h b/src/zig_llvm.h
index c2c4b4dd7..24e14f2f7 100644
--- a/src/zig_llvm.h
+++ b/src/zig_llvm.h
@@ -51,9 +51,16 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi
         bool is_small, bool time_report,
         const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename);
 
+
+enum ZigLLVMABIType {
+    ZigLLVMABITypeDefault, // Target-specific (either soft or hard depending on triple, etc).
+    ZigLLVMABITypeSoft,    // Soft float.
+    ZigLLVMABITypeHard     // Hard float.
+};
+
 ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple,
     const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
-    LLVMCodeModel CodeModel, bool function_sections);
+    LLVMCodeModel CodeModel, bool function_sections, ZigLLVMABIType float_abi);
 
 ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref);
 

Still got the error "cannot link object files with different floating-point ABI".

I wonder what the clang argumentsl -mabi=ilp32d / -mabi=lp64d are doing in terms of the LLVM API.

@andrewrk
Copy link
Member Author

andrewrk commented Apr 3, 2020

@luismarques do you have any clues? What LLVM API do we need to match clang's behavior here?

@LemonBoy
Copy link
Contributor

LemonBoy commented Apr 3, 2020

The -mabi switch translates to this field in TargetOptions.MCOptions. The float ABI switch is also nice to have.

andrewrk added a commit that referenced this issue Apr 3, 2020
Before, this would cause a link failure when mixing Zig and C code for
RISC-V targets.

Now, the ABIs match and Zig and C code can be mixed successfully.

I will file a follow-up issue for the ability to deal more explicitly
with ABIs.

closes #4863
andrewrk added a commit that referenced this issue Apr 3, 2020
Before, this would cause a link failure when mixing Zig and C code for
RISC-V targets.

Now, the ABIs match and Zig and C code can be mixed successfully.

I will file a follow-up issue for the ability to deal more explicitly
with ABIs.

closes #4863
@andrewrk andrewrk modified the milestones: 0.7.0, 0.6.0 Apr 3, 2020
@luismarques
Copy link

@luismarques do you have any clues? What LLVM API do we need to match clang's behavior here?

Sorry, with the UK lockdown and the nurseries closing my available time has dramatically diminished, so I haven't been able to look into this.

@andrewrk
Copy link
Member Author

No worries @luismarques - btw this issue was solved with 11b50e3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch-riscv RISCV-32 and RISCV-64
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants