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

LLVM assertion tripped when building compiler_rt for sparc64 #12011

Closed
andrewrk opened this issue Jul 5, 2022 · 7 comments
Closed

LLVM assertion tripped when building compiler_rt for sparc64 #12011

andrewrk opened this issue Jul 5, 2022 · 7 comments
Labels
arch-sparc 32-bit and 64-bit SPARC backend-llvm The LLVM backend outputs an LLVM IR Module. bug Observed behavior contradicts documented or intended behavior contributor friendly This issue is limited in scope and/or knowledge of Zig internals. upstream An issue with a third party project that Zig uses.
Milestone

Comments

@andrewrk
Copy link
Member

andrewrk commented Jul 5, 2022

Zig Version: 0.10.0-dev.2848+86570b3e2

const msg = "Hello, World!\n";

fn length() usize {
    return msg.len;
}

pub fn main() void {
    asm volatile ("ta 0x6d"
        :
        : [number] "{g1}" (4),
          [arg1] "{o0}" (1),
          [arg2] "{o1}" (@ptrToInt(msg)),
          [arg3] "{o2}" (length()),
        : "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7", "memory"
    );
}

// run
// target=sparc64-linux
//
// Hello, World!
//

This is tripping an assertion when using a debug build of LLVM 13, during the optimization of the fmaq function of compiler-rt:

test: /home/andy/Downloads/llvm-project-13/llvm/include/llvm/CodeGen/CallingConvLower.h:150: llvm::Register llvm::CCValAssign::getLocReg() const: Assertion `isRegLoc()' failed.

(gdb) p Fn.dump()
; Function Attrs: nobuiltin noredzone nounwind
define weak_odr dso_local fp128 @fmaq(fp128 %0, fp128 %1, fp128 %2) local_unnamed_addr #1 {
Entry:
  %3 = bitcast fp128 %0 to i128
  %4 = and i128 %3, 170135991163610696904058773219554885632
  %.not = icmp eq i128 %4, 170135991163610696904058773219554885632
  br i1 %.not, label %Then1, label %Else

Else:                                             ; preds = %Entry
  %5 = bitcast fp128 %1 to i128
  %6 = and i128 %5, 170135991163610696904058773219554885632
  %.not76 = icmp eq i128 %6, 170135991163610696904058773219554885632
  br i1 %.not76, label %Then1, label %Block3

common.ret:                                       ; preds = %Block3, %Else23, %Then22, %Then19, %Then13, %Then10, %Then1
  %common.ret.op = phi fp128 [ %8, %Then1 ], [ %15, %Then10 ], [ %17, %Then13 ], [ %55, %Then19 ], [ %76, %Then22 ], [ %77, %Else23 ], [ %2, %Block3 ]
  ret fp128 %common.ret.op

Then1:                                            ; preds = %Entry, %Else
  %7 = fmul fp128 %0, %1
  %8 = fadd fp128 %7, %2
  br label %common.ret

Block3:                                           ; preds = %Else
  %9 = bitcast fp128 %2 to i128
  %10 = and i128 %9, 170135991163610696904058773219554885632
  %.not77 = icmp eq i128 %10, 170135991163610696904058773219554885632
  br i1 %.not77, label %common.ret, label %Block6

Block6:                                           ; preds = %Block3
  %11 = fcmp oeq fp128 %0, 0xL00000000000000000000000000000000
  %12 = fcmp oeq fp128 %1, 0xL00000000000000000000000000000000
  %13 = select i1 %11, i1 true, i1 %12
  br i1 %13, label %Then10, label %Block12

Then10:                                           ; preds = %Block6
  %14 = fmul fp128 %0, %1
  %15 = fadd fp128 %14, %2
  br label %common.ret

Block12:                                          ; preds = %Block6
  %16 = fcmp oeq fp128 %2, 0xL00000000000000000000000000000000
  br i1 %16, label %Then13, label %Block15

Then13:                                           ; preds = %Block12
  %17 = fmul fp128 %0, %1
  br label %common.ret

Block15:                                          ; preds = %Block12
  %18 = tail call fastcc { fp128, i32, [12 x i8] } @math.frexp.frexp128(fp128 %0) #12
  %newret3.i = extractvalue { fp128, i32, [12 x i8] } %18, 0
  %newret5.i = extractvalue { fp128, i32, [12 x i8] } %18, 1
  %19 = tail call fastcc { fp128, i32, [12 x i8] } @math.frexp.frexp128(fp128 %1) #12
  %newret3.i64 = extractvalue { fp128, i32, [12 x i8] } %19, 0
  %newret5.i65 = extractvalue { fp128, i32, [12 x i8] } %19, 1
  %20 = tail call fastcc { fp128, i32, [12 x i8] } @math.frexp.frexp128(fp128 %2) #12
  %newret3.i68 = extractvalue { fp128, i32, [12 x i8] } %20, 0
  %newret5.i69 = extractvalue { fp128, i32, [12 x i8] } %20, 1
  %21 = add nsw i32 %newret5.i65, %newret5.i
  %22 = sub nsw i32 %21, %newret5.i69
  %23 = icmp slt i32 %22, 227
  br i1 %23, label %Then16, label %Else17

Then16:                                           ; preds = %Block15
  %24 = sub nsw i32 0, %22
  %25 = tail call fastcc fp128 @math.ldexp.ldexp__anon_3223(fp128 %newret3.i68, i32 %24)
  br label %Block18

Else17:                                           ; preds = %Block15
  %26 = bitcast fp128 %newret3.i68 to i128
  %27 = and i128 %26, -170141183460469231731687303715884105728
  %28 = or i128 %27, 5192296858534827628530496329220096
  %29 = bitcast i128 %28 to fp128
  br label %Block18

Block18:                                          ; preds = %Else17, %Then16
  %.0 = phi fp128 [ %25, %Then16 ], [ %29, %Else17 ]
  %30 = fmul fp128 %newret3.i, 0xL00800000000000004038000000000000
  %31 = fsub fp128 %newret3.i, %30
  %32 = fadd fp128 %30, %31
  %33 = fsub fp128 %newret3.i, %32
  %34 = fmul fp128 %newret3.i64, 0xL00800000000000004038000000000000
  %35 = fsub fp128 %newret3.i64, %34
  %36 = fadd fp128 %34, %35
  %37 = fsub fp128 %newret3.i64, %36
  %38 = fmul fp128 %32, %36
  %39 = fmul fp128 %32, %37
  %40 = fmul fp128 %33, %36
  %41 = fadd fp128 %40, %39
  %42 = fadd fp128 %38, %41
  %43 = fsub fp128 %38, %42
  %44 = fadd fp128 %41, %43
  %45 = fmul fp128 %33, %37
  %46 = fadd fp128 %45, %44
  %47 = fadd fp128 %42, %.0
  %48 = fsub fp128 %47, %42
  %49 = fsub fp128 %47, %48
  %50 = fsub fp128 %42, %49
  %51 = fsub fp128 %.0, %48
  %52 = fadd fp128 %51, %50
  %53 = fcmp oeq fp128 %47, 0xL00000000000000000000000000000000
  br i1 %53, label %Then19, label %Block21

Then19:                                           ; preds = %Block18
  %54 = tail call fastcc fp128 @math.ldexp.ldexp__anon_3223(fp128 %46, i32 %21)
  %55 = fadd fp128 %47, %54
  br label %common.ret

Block21:                                          ; preds = %Block18
  %56 = fadd fp128 %46, %52
  %57 = fsub fp128 %56, %52
  %58 = fsub fp128 %56, %57
  %59 = fsub fp128 %52, %58
  %60 = fsub fp128 %46, %57
  %61 = fadd fp128 %60, %59
  %62 = fcmp une fp128 %61, 0xL00000000000000000000000000000000
  br i1 %62, label %Then.i, label %compiler_rt.fma.add_adjusted128.exit

Then.i:                                           ; preds = %Block21
  %63 = bitcast fp128 %56 to i128
  %64 = and i128 %63, 1
  %65 = icmp eq i128 %64, 0
  br i1 %65, label %Then1.i, label %compiler_rt.fma.add_adjusted128.exit

Then1.i:                                          ; preds = %Then.i
  %66 = bitcast fp128 %61 to i128
  %67 = xor i128 %66, %63
  %68 = lshr i128 %67, 126
  %69 = add nuw i128 %63, 1
  %70 = sub i128 %69, %68
  %71 = bitcast i128 %70 to fp128
  br label %compiler_rt.fma.add_adjusted128.exit

compiler_rt.fma.add_adjusted128.exit:             ; preds = %Block21, %Then.i, %Then1.i
  %.sroa.0.0.i = phi fp128 [ %71, %Then1.i ], [ %56, %Then.i ], [ %56, %Block21 ]
  %72 = tail call fastcc i32 @math.ilogb.ilogb__anon_3226(fp128 %47)
  %73 = add nsw i32 %72, %21
  %74 = icmp sgt i32 %73, -16383
  br i1 %74, label %Then22, label %Else23

Then22:                                           ; preds = %compiler_rt.fma.add_adjusted128.exit
  %75 = fadd fp128 %47, %.sroa.0.0.i
  %76 = tail call fastcc fp128 @math.ldexp.ldexp__anon_3223(fp128 %75, i32 %21)
  br label %common.ret

Else23:                                           ; preds = %compiler_rt.fma.add_adjusted128.exit
  %77 = tail call fastcc fp128 @compiler_rt.fma.add_and_denorm128(fp128 %47, fp128 %.sroa.0.0.i, i32 %21)
  br label %common.ret
}

$1 = void


(gdb) bt
#0  0x00007ffff7cabbda in raise () from /nix/store/0xxjx37fcy2nl3yz6igmv4mag2a7giq6-glibc-2.33-123/lib/libc.so.6
#1  0x00007ffff7c96533 in abort () from /nix/store/0xxjx37fcy2nl3yz6igmv4mag2a7giq6-glibc-2.33-123/lib/libc.so.6
#2  0x00007ffff7c9642f in __assert_fail_base.cold.0 () from /nix/store/0xxjx37fcy2nl3yz6igmv4mag2a7giq6-glibc-2.33-123/lib/libc.so.6
#3  0x00007ffff7ca4622 in __assert_fail () from /nix/store/0xxjx37fcy2nl3yz6igmv4mag2a7giq6-glibc-2.33-123/lib/libc.so.6
#4  0x00000000099ceeff in llvm::CCValAssign::getLocReg (this=0x7ffffffee6dc) at /home/andy/Downloads/llvm-project-13/llvm/include/llvm/CodeGen/CallingConvLower.h:150
#5  0x000000000ad06a35 in llvm::SparcTargetLowering::LowerCall_64 (this=0x118757b8, CLI=..., InVals=...) at /home/andy/Downloads/llvm-project-13/llvm/lib/Target/Sparc/SparcISelLowering.cpp:1303
#6  0x000000000ad0140c in llvm::SparcTargetLowering::LowerCall (this=0x118757b8, CLI=..., InVals=...) at /home/andy/Downloads/llvm-project-13/llvm/lib/Target/Sparc/SparcISelLowering.cpp:688
#7  0x0000000009a7fec5 in llvm::TargetLowering::LowerCallTo (this=0x118757b8, CLI=...) at /home/andy/Downloads/llvm-project-13/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:9697
#8  0x0000000009a73b90 in llvm::SelectionDAGBuilder::lowerInvokable (this=0xf3e3660, CLI=..., EHPadBB=0x0) at /home/andy/Downloads/llvm-project-13/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:7430
#9  0x0000000009a74444 in llvm::SelectionDAGBuilder::LowerCallTo (this=0xf3e3660, CB=..., Callee=..., isTailCall=false, isMustTailCall=false, EHPadBB=0x0) at /home/andy/Downloads/llvm-project-13/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:7548
#10 0x0000000009a76e11 in llvm::SelectionDAGBuilder::visitCall (this=0xf3e3660, I=...) at /home/andy/Downloads/llvm-project-13/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:8100
#11 0x0000000009a48be1 in llvm::SelectionDAGBuilder::visit (this=0xf3e3660, Opcode=56, I=...) at /home/andy/Downloads/llvm-project-13/llvm/include/llvm/IR/Instruction.def:209
#12 0x0000000009a485bd in llvm::SelectionDAGBuilder::visit (this=0xf3e3660, I=...) at /home/andy/Downloads/llvm-project-13/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:1116
#13 0x0000000009bb1883 in llvm::SelectionDAGISel::SelectBasicBlock (this=0xec751a0, Begin=..., End=..., HadTailCall=@0x7fffffff0f7f: false) at /home/andy/Downloads/llvm-project-13/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:717
#14 0x0000000009bb6408 in llvm::SelectionDAGISel::SelectAllBasicBlocks (this=0xec751a0, Fn=...) at /home/andy/Downloads/llvm-project-13/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1622
#15 0x0000000009bb04e8 in llvm::SelectionDAGISel::runOnMachineFunction (this=0xec751a0, mf=...) at /home/andy/Downloads/llvm-project-13/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:509
#16 0x000000000ad17bd4 in (anonymous namespace)::SparcDAGToDAGISel::runOnMachineFunction (this=0xec751a0, MF=...) at /home/andy/Downloads/llvm-project-13/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:40
#17 0x0000000007ea8730 in llvm::MachineFunctionPass::runOnFunction (this=0xec751a0, F=...) at /home/andy/Downloads/llvm-project-13/llvm/lib/CodeGen/MachineFunctionPass.cpp:72
#18 0x0000000007833d77 in llvm::FPPassManager::runOnFunction (this=0x11f68230, F=...) at /home/andy/Downloads/llvm-project-13/llvm/lib/IR/LegacyPassManager.cpp:1439
#19 0x0000000007833fe0 in llvm::FPPassManager::runOnModule (this=0x11f68230, M=...) at /home/andy/Downloads/llvm-project-13/llvm/lib/IR/LegacyPassManager.cpp:1485
#20 0x000000000783440a in (anonymous namespace)::MPPassManager::runOnModule (this=0xf52cf10, M=...) at /home/andy/Downloads/llvm-project-13/llvm/lib/IR/LegacyPassManager.cpp:1554
#21 0x000000000782faaa in llvm::legacy::PassManagerImpl::run (this=0x11ff8f70, M=...) at /home/andy/Downloads/llvm-project-13/llvm/lib/IR/LegacyPassManager.cpp:542
#22 0x0000000007834bef in llvm::legacy::PassManager::run (this=0x7fffffff1aa0, M=...) at /home/andy/Downloads/llvm-project-13/llvm/lib/IR/LegacyPassManager.cpp:1681
#23 0x0000000007cc1a50 in ZigLLVMTargetMachineEmitToFile (targ_machine_ref=0x12a2c320, module_ref=0x141d8380, error_message=0x7fffffff30c0, is_debug=false, is_small=false, time_report=false, tsan=false, lto=false, asm_filename=0x0, bin_filename=0x11f84b36 "./zig-cache/tmp/JqGUBWEs5e1PIECl/zig-cache/o/d3f7caa326a8165de27dd2861b5c7242/libcompiler_rt.a.o", llvm_ir_filename=0x0, bitcode_filename=0x0) at /home/andy/Downloads/zig/src/zig_llvm.cpp:389
#24 0x000000000629fa53 in codegen.llvm.Object.flushModule (self=0xfe96620, comp=0xe7c4318, prog_node=0x7fffffff4ef0) at /home/andy/Downloads/zig/src/codegen/llvm.zig:643
#25 0x00000000062b363c in link.Elf.flushModule (self=0xf558820, comp=0xe7c4318, prog_node=0x7fffffff4ef0) at /home/andy/Downloads/zig/src/link/Elf.zig:960
#26 0x000000000629e5bf in link.File.flushModule (base=0xf558820, comp=0xe7c4318, prog_node=0x7fffffff4ef0) at link.zig:656
#27 0x000000000629b8ed in link.File.linkAsArchive (base=0xf558820, comp=0xe7c4318, prog_node=0x7fffffff4ef0) at link.zig:832
#28 0x000000000629ab15 in link.File.flush (base=0xf558820, comp=0xe7c4318, prog_node=0x7fffffff4ef0) at link.zig:637
#29 0x0000000006264959 in Compilation.flush (comp=0xe7c4318, prog_node=0x7fffffff4ef0) at Compilation.zig:2325
#30 0x00000000061d01a1 in Compilation.update (comp=0xe7c4318) at Compilation.zig:2293
#31 0x000000000648c503 in Compilation.buildOutputFromZig (comp=0xeb857c8, src_basename=..., output_mode=Lib, out=0xeb85b10, misc_task_tag=compiler_rt) at Compilation.zig:5025
#32 0x0000000006273ad5 in Compilation.buildCompilerRtOneShot (comp=0xeb857c8, output_mode=Lib, out=0xeb85b10) at Compilation.zig:3550
#33 0x0000000006260970 in Compilation.performAllTheWork (comp=0xeb857c8, main_progress_node=0x7fffffff6a10) at Compilation.zig:2881
#34 0x00000000061cf703 in Compilation.update (comp=0xeb857c8) at Compilation.zig:2218
#35 0x000000000619f1d9 in TestContext.runOneCase (allocator=..., root_node=0x7fffffff92f8, case=..., zig_lib_directory=..., thread_pool=0x7fffffff97d8, global_cache_directory=..., host=...) at test.zig:1611
#36 0x000000000619c057 in TestContext.workerRunOneCase (gpa=..., root_node=0x7fffffff9ac0, case=0x7ffff79e3130, zig_lib_directory=..., thread_pool=0x7fffffff97d8, global_cache_directory=..., host=..., wait_group=0x7fffffff96a0) at test.zig:1327
#37 0x0000000006196875 in ThreadPool.spawn (pool=0x7fffffff97a0, args=<error reading variable: Cannot access memory at address 0x2>) at ThreadPool.zig:77
#38 0x000000000618c73d in TestContext.run (self=0x7fffffff9f90) at test.zig:1284
#39 0x000000000615edc0 in test "" () at test.zig:65
#40 0x000000000618d206 in (root).main () at /home/andy/Downloads/zig/lib/test_runner.zig:79
#41 0x00000000061eb59d in std.start.callMain () at /home/andy/Downloads/zig/lib/std/start.zig:571
#42 0x000000000618ee48 in std.start.initEventLoopAndCallMain () at /home/andy/Downloads/zig/lib/std/start.zig:515
#43 std.start.callMainWithArgs (argc=2, argv=0x7fffffffa6c8, envp=...) at /home/andy/Downloads/zig/lib/std/start.zig:465
#44 0x000000000618ebf3 in std.start.main (c_argc=2, c_argv=0x7fffffffa6c8, c_envp=0x7fffffffa6e0) at /home/andy/Downloads/zig/lib/std/start.zig:480

This is a bug in LLVM 13. The next steps are:

  • confirm the bug exists in trunk
  • use llvm-reduce to reduce the LLVM IR code
  • report the bug upstream

Until then this test case will be disabled so that we are not tripping LLVM assertions.

@andrewrk andrewrk added bug Observed behavior contradicts documented or intended behavior contributor friendly This issue is limited in scope and/or knowledge of Zig internals. upstream An issue with a third party project that Zig uses. arch-sparc 32-bit and 64-bit SPARC backend-llvm The LLVM backend outputs an LLVM IR Module. labels Jul 5, 2022
@andrewrk andrewrk added this to the 0.12.0 milestone Jul 5, 2022
wooster0 pushed a commit to wooster0/zig that referenced this issue Jul 24, 2022
@koachan
Copy link
Contributor

koachan commented Aug 6, 2022

A minimal testcase for it:

declare { [12 x i8] } @callee()

define void @caller() {
  call { [12 x i8] } @callee()
  ret void
}

Seems like the [12 x i8] return of @math.frexp.frexp128 is triggering it - LLVM tries to do SROA optimization on that array but it fails (there's too many values such that it can't fit in the return registers) and since there seems to be no fallback code, it hard-crashes instead.

Will look into it 👀

@koachan
Copy link
Contributor

koachan commented Aug 23, 2022

Upstream patch ticket: https://reviews.llvm.org/D132465

@matu3ba
Copy link
Contributor

matu3ba commented Feb 13, 2023

Upstream patch landed as of d3fcbee10d89 on Oct 17 2022, 5:02 PM. Can anybody validate, that the problem does not occur anymore on sparc64?

@koachan
Copy link
Contributor

koachan commented Feb 14, 2023

Yeah. With patched LLVM, the testcase in the OP does not error anymore when building for sparc64-linux for me.

@nektro
Copy link
Contributor

nektro commented Feb 14, 2023

the aforementioned commit landed in llvm 16 so we'll be able to close once zig changes over

TUSF pushed a commit to TUSF/zig that referenced this issue May 9, 2024
@alexrp
Copy link
Member

alexrp commented Aug 3, 2024

Looks like this can be closed.

Edit: I tried restoring the test case, but it hits llvm/llvm-project#103493.

@alexrp alexrp mentioned this issue Aug 24, 2024
7 tasks
@andrewrk
Copy link
Member Author

Fixed with the merge of LLVM 19 branch in c6ad452.

@andrewrk andrewrk modified the milestones: 0.16.0, 0.14.0 Sep 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch-sparc 32-bit and 64-bit SPARC backend-llvm The LLVM backend outputs an LLVM IR Module. bug Observed behavior contradicts documented or intended behavior contributor friendly This issue is limited in scope and/or knowledge of Zig internals. upstream An issue with a third party project that Zig uses.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants