zig icon indicating copy to clipboard operation
zig copied to clipboard

LLVM assertion tripped when building compiler_rt for sparc64

Open andrewrk opened this issue 3 years ago • 6 comments

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 avatar Jul 05 '22 23:07 andrewrk

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 :eyes:

koachan avatar Aug 06 '22 07:08 koachan

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

koachan avatar Aug 23 '22 12:08 koachan

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?

matu3ba avatar Feb 13 '23 23:02 matu3ba

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

koachan avatar Feb 14 '23 08:02 koachan

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

nektro avatar Feb 14 '23 22:02 nektro

~~Looks like this can be closed.~~

Edit: I tried restoring the test case, but it hits https://github.com/llvm/llvm-project/issues/103493.

alexrp avatar Aug 03 '24 00:08 alexrp

Fixed with the merge of LLVM 19 branch in c6ad4521c77372cb52adfb9a52b0854d830fed9c.

andrewrk avatar Sep 20 '24 05:09 andrewrk