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

ICE with debug info (LLVM assert) #2216

Closed
JohanEngelen opened this issue Jul 18, 2017 · 4 comments
Closed

ICE with debug info (LLVM assert) #2216

JohanEngelen opened this issue Jul 18, 2017 · 4 comments

Comments

@JohanEngelen
Copy link
Member

A minimized testcase for the debuginfo bug that we see with LLVM >= 4.0 with asserts enabled (Semaphore)

// ldc2 -g test.d
real[1] b;
void testx()
{
    b[] = b[] + 4;

    b[] = 4 + b[];
}
@kinke
Copy link
Member

kinke commented Jul 23, 2017

The IR looks pretty bad:

; [#uses = 2] [display name = current._arraySliceExpAddSliceAssign_e]
; Function Attrs: uwtable
define weak_odr { i64, x86_fp80* } @_arraySliceExpAddSliceAssign_e({ i64, x86_fp80* } %p2_arg, x86_fp80 %c1_arg, { i64, x86_fp80* } %p0_arg) #0 comdat !dbg !19 {
  %p2 = alloca { i64, x86_fp80* }, align 8        ; [#uses = 6, size/byte = 16]
  %c1 = alloca x86_fp80, align 16                 ; [#uses = 2, size/byte = 16]
  %p0 = alloca { i64, x86_fp80* }, align 8        ; [#uses = 3, size/byte = 16]
  %__key55 = alloca i64, align 8                  ; [#uses = 5, size/byte = 8]
  %__limit56 = alloca i64, align 8                ; [#uses = 2, size/byte = 8]
  %p = alloca i64, align 8                        ; [#uses = 5, size/byte = 8]
  store { i64, x86_fp80* } %p2_arg, { i64, x86_fp80* }* %p2, !dbg !42 ; [debug line = current.d:1]
  call void @llvm.dbg.declare(metadata { i64, x86_fp80* }* %p2, metadata !45, metadata !53), !dbg !54 ; [debug line = current.d:0] [debug variable = p2]
  store x86_fp80 %c1_arg, x86_fp80* %c1, !dbg !42 ; [debug line = current.d:1]
  call void @llvm.dbg.declare(metadata x86_fp80* %c1, metadata !46, metadata !53), !dbg !54 ; [debug line = current.d:0] [debug variable = c1]
  store { i64, x86_fp80* } %p0_arg, { i64, x86_fp80* }* %p0, !dbg !42 ; [debug line = current.d:1]
  call void @llvm.dbg.declare(metadata { i64, x86_fp80* }* %p0, metadata !47, metadata !53), !dbg !54 ; [debug line = current.d:0] [debug variable = p0]
  call void @llvm.dbg.declare(metadata i64* %__key55, metadata !48, metadata !53), !dbg !55 ; [debug line = current.d:0] [debug variable = __key55]
  store i64 0, i64* %__key55, !dbg !42            ; [debug line = current.d:1]
  call void @llvm.dbg.declare(metadata i64* %__limit56, metadata !50, metadata !53), !dbg !55 ; [debug line = current.d:0] [debug variable = __limit56]
  %1 = getelementptr inbounds { i64, x86_fp80* }, { i64, x86_fp80* }* %p2, i32 0, i32 0 ; [#uses = 1, type = i64*]
  %.len = load i64, i64* %1, !dbg !42             ; [#uses = 1] [debug line = current.d:1]
  store i64 %.len, i64* %__limit56, !dbg !42      ; [debug line = current.d:1]
  br label %forcond

forcond:                                          ; preds = %forinc, %0
  %2 = load i64, i64* %__key55, !dbg !42          ; [#uses = 1] [debug line = current.d:1]
  %3 = load i64, i64* %__limit56, !dbg !42        ; [#uses = 1] [debug line = current.d:1]
  %4 = icmp ult i64 %2, %3, !dbg !42              ; [#uses = 1] [debug line = current.d:1]
  br i1 %4, label %forbody, label %endfor

forbody:                                          ; preds = %forcond
  call void @llvm.dbg.declare(metadata i64* %p, metadata !51, metadata !53), !dbg !56 ; [debug line = current.d:0] [debug variable = p]
  %5 = load i64, i64* %__key55, !dbg !42          ; [#uses = 1] [debug line = current.d:1]
  store i64 %5, i64* %p, !dbg !42                 ; [debug line = current.d:1]
  %6 = load i64, i64* %p, !dbg !42                ; [#uses = 1] [debug line = current.d:1]
  %7 = getelementptr inbounds { i64, x86_fp80* }, { i64, x86_fp80* }* %p2, i32 0, i32 0 ; [#uses = 1, type = i64*]
  %.len1 = load i64, i64* %7, !dbg !42            ; [#uses = 1] [debug line = current.d:1]
  %bounds.cmp = icmp ult i64 %6, %.len1, !dbg !42 ; [#uses = 1] [debug line = current.d:1]
  br i1 %bounds.cmp, label %bounds.ok, label %bounds.fail, !dbg !42 ; [debug line = current.d:1]

bounds.ok:                                        ; preds = %forbody
  %8 = load i64, i64* %p, !dbg !42                ; [#uses = 1] [debug line = current.d:1]
  %9 = getelementptr inbounds { i64, x86_fp80* }, { i64, x86_fp80* }* %p2, i32 0, i32 1 ; [#uses = 1, type = x86_fp80**]
  %.ptr = load x86_fp80*, x86_fp80** %9, !dbg !42 ; [#uses = 1] [debug line = current.d:1]
  %10 = getelementptr x86_fp80, x86_fp80* %.ptr, i64 %8 ; [#uses = 1, type = x86_fp80*]
  %11 = load i64, i64* %p, !dbg !42               ; [#uses = 1] [debug line = current.d:1]
  %12 = getelementptr inbounds { i64, x86_fp80* }, { i64, x86_fp80* }* %p0, i32 0, i32 0 ; [#uses = 1, type = i64*]
  %.len2 = load i64, i64* %12, !dbg !42           ; [#uses = 1] [debug line = current.d:1]
  %bounds.cmp3 = icmp ult i64 %11, %.len2, !dbg !42 ; [#uses = 1] [debug line = current.d:1]
  br i1 %bounds.cmp3, label %bounds.ok4, label %bounds.fail5, !dbg !42 ; [debug line = current.d:1]

bounds.ok4:                                       ; preds = %bounds.ok
  %13 = load i64, i64* %p, !dbg !42               ; [#uses = 1] [debug line = current.d:1]
  %14 = getelementptr inbounds { i64, x86_fp80* }, { i64, x86_fp80* }* %p0, i32 0, i32 1 ; [#uses = 1, type = x86_fp80**]
  %.ptr6 = load x86_fp80*, x86_fp80** %14, !dbg !42 ; [#uses = 1] [debug line = current.d:1]
  %15 = getelementptr x86_fp80, x86_fp80* %.ptr6, i64 %13 ; [#uses = 1, type = x86_fp80*]
  %16 = load x86_fp80, x86_fp80* %15, !dbg !42    ; [#uses = 1] [debug line = current.d:1]
  %17 = load x86_fp80, x86_fp80* %c1, !dbg !42    ; [#uses = 1] [debug line = current.d:1]
  %18 = fadd x86_fp80 %16, %17, !dbg !42          ; [#uses = 1] [debug line = current.d:1]
  store x86_fp80 %18, x86_fp80* %10, !dbg !42     ; [debug line = current.d:1]
  br label %forinc

bounds.fail5:                                     ; preds = %bounds.ok
  call void @_d_arraybounds({ i64, i8* } { i64 12, i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i32 0, i32 0) }, i32 0) #2, !dbg !42 ; [debug line = current.d:1]
  unreachable, !dbg !42                           ; [debug line = current.d:1]

bounds.fail:                                      ; preds = %forbody
  call void @_d_arraybounds({ i64, i8* } { i64 12, i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i32 0, i32 0) }, i32 0) #2, !dbg !42 ; [debug line = current.d:1]
  unreachable, !dbg !42                           ; [debug line = current.d:1]

forinc:                                           ; preds = %bounds.ok4
  %19 = load i64, i64* %__key55, !dbg !42         ; [#uses = 1] [debug line = current.d:1]
  %20 = add i64 %19, 1, !dbg !42                  ; [#uses = 1] [debug line = current.d:1]
  store i64 %20, i64* %__key55, !dbg !42          ; [debug line = current.d:1]
  br label %forcond

endfor:                                           ; preds = %forcond
  %21 = load { i64, x86_fp80* }, { i64, x86_fp80* }* %p2, !dbg !42 ; [#uses = 0] [debug line = current.d:1]
  %22 = load { i64, x86_fp80* }, { i64, x86_fp80* }* %p2, !dbg !42 ; [#uses = 1] [debug line = current.d:1]
  ret { i64, x86_fp80* } %22, !dbg !42            ; [debug line = current.d:1]
                                                  ; No predecessors!
  %p27 = alloca { i64, x86_fp80* }, align 8       ; [#uses = 6, size/byte = 16]
  %c18 = alloca x86_fp80, align 16                ; [#uses = 2, size/byte = 16]
  %p09 = alloca { i64, x86_fp80* }, align 8       ; [#uses = 3, size/byte = 16]
  %__key57 = alloca i64, align 8                  ; [#uses = 5, size/byte = 8]
  %__limit58 = alloca i64, align 8                ; [#uses = 2, size/byte = 8]
  %p15 = alloca i64, align 8                      ; [#uses = 5, size/byte = 8]
  store { i64, x86_fp80* } %p2_arg, { i64, x86_fp80* }* %p27, !dbg !57 ; [debug line = current.d:1]
  call void @llvm.dbg.declare(metadata { i64, x86_fp80* }* %p27, metadata !29, metadata !53), !dbg !58 ; [debug line = current.d:0] [debug variable = p2]
  store x86_fp80 %c1_arg, x86_fp80* %c18, !dbg !57 ; [debug line = current.d:1]
  call void @llvm.dbg.declare(metadata x86_fp80* %c18, metadata !30, metadata !53), !dbg !58 ; [debug line = current.d:0] [debug variable = c1]
  store { i64, x86_fp80* } %p0_arg, { i64, x86_fp80* }* %p09, !dbg !57 ; [debug line = current.d:1]
  call void @llvm.dbg.declare(metadata { i64, x86_fp80* }* %p09, metadata !31, metadata !53), !dbg !58 ; [debug line = current.d:0] [debug variable = p0]
  call void @llvm.dbg.declare(metadata i64* %__key57, metadata !37, metadata !53), !dbg !59 ; [debug line = current.d:0] [debug variable = __key57]
  store i64 0, i64* %__key57, !dbg !57            ; [debug line = current.d:1]
  call void @llvm.dbg.declare(metadata i64* %__limit58, metadata !39, metadata !53), !dbg !59 ; [debug line = current.d:0] [debug variable = __limit58]
  %24 = getelementptr inbounds { i64, x86_fp80* }, { i64, x86_fp80* }* %p27, i32 0, i32 0 ; [#uses = 1, type = i64*]
  %.len10 = load i64, i64* %24, !dbg !57          ; [#uses = 1] [debug line = current.d:1]
  store i64 %.len10, i64* %__limit58, !dbg !57    ; [debug line = current.d:1]
  br label %forcond11

forcond11:                                        ; preds = %forinc13, %23
  %25 = load i64, i64* %__key57, !dbg !57         ; [#uses = 1] [debug line = current.d:1]
  %26 = load i64, i64* %__limit58, !dbg !57       ; [#uses = 1] [debug line = current.d:1]
  %27 = icmp ult i64 %25, %26, !dbg !57           ; [#uses = 1] [debug line = current.d:1]
  br i1 %27, label %forbody12, label %endfor14

forbody12:                                        ; preds = %forcond11
  call void @llvm.dbg.declare(metadata i64* %p15, metadata !40, metadata !53), !dbg !60 ; [debug line = current.d:0] [debug variable = p]
  %28 = load i64, i64* %__key57, !dbg !57         ; [#uses = 1] [debug line = current.d:1]
  store i64 %28, i64* %p15, !dbg !57              ; [debug line = current.d:1]
  %29 = load i64, i64* %p15, !dbg !57             ; [#uses = 1] [debug line = current.d:1]
  %30 = getelementptr inbounds { i64, x86_fp80* }, { i64, x86_fp80* }* %p27, i32 0, i32 0 ; [#uses = 1, type = i64*]
  %.len16 = load i64, i64* %30, !dbg !57          ; [#uses = 1] [debug line = current.d:1]
  %bounds.cmp17 = icmp ult i64 %29, %.len16, !dbg !57 ; [#uses = 1] [debug line = current.d:1]
  br i1 %bounds.cmp17, label %bounds.ok18, label %bounds.fail19, !dbg !57 ; [debug line = current.d:1]

bounds.ok18:                                      ; preds = %forbody12
  %31 = load i64, i64* %p15, !dbg !57             ; [#uses = 1] [debug line = current.d:1]
  %32 = getelementptr inbounds { i64, x86_fp80* }, { i64, x86_fp80* }* %p27, i32 0, i32 1 ; [#uses = 1, type = x86_fp80**]
  %.ptr20 = load x86_fp80*, x86_fp80** %32, !dbg !57 ; [#uses = 1] [debug line = current.d:1]
  %33 = getelementptr x86_fp80, x86_fp80* %.ptr20, i64 %31 ; [#uses = 1, type = x86_fp80*]
  %34 = load i64, i64* %p15, !dbg !57             ; [#uses = 1] [debug line = current.d:1]
  %35 = getelementptr inbounds { i64, x86_fp80* }, { i64, x86_fp80* }* %p09, i32 0, i32 0 ; [#uses = 1, type = i64*]
  %.len21 = load i64, i64* %35, !dbg !57          ; [#uses = 1] [debug line = current.d:1]
  %bounds.cmp22 = icmp ult i64 %34, %.len21, !dbg !57 ; [#uses = 1] [debug line = current.d:1]
  br i1 %bounds.cmp22, label %bounds.ok23, label %bounds.fail24, !dbg !57 ; [debug line = current.d:1]

bounds.ok23:                                      ; preds = %bounds.ok18
  %36 = load i64, i64* %p15, !dbg !57             ; [#uses = 1] [debug line = current.d:1]
  %37 = getelementptr inbounds { i64, x86_fp80* }, { i64, x86_fp80* }* %p09, i32 0, i32 1 ; [#uses = 1, type = x86_fp80**]
  %.ptr25 = load x86_fp80*, x86_fp80** %37, !dbg !57 ; [#uses = 1] [debug line = current.d:1]
  %38 = getelementptr x86_fp80, x86_fp80* %.ptr25, i64 %36 ; [#uses = 1, type = x86_fp80*]
  %39 = load x86_fp80, x86_fp80* %38, !dbg !57    ; [#uses = 1] [debug line = current.d:1]
  %40 = load x86_fp80, x86_fp80* %c18, !dbg !57   ; [#uses = 1] [debug line = current.d:1]
  %41 = fadd x86_fp80 %39, %40, !dbg !57          ; [#uses = 1] [debug line = current.d:1]
  store x86_fp80 %41, x86_fp80* %33, !dbg !57     ; [debug line = current.d:1]
  br label %forinc13

bounds.fail24:                                    ; preds = %bounds.ok18
  call void @_d_arraybounds({ i64, i8* } { i64 12, i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i32 0, i32 0) }, i32 0) #2, !dbg !57 ; [debug line = current.d:1]
  unreachable, !dbg !57                           ; [debug line = current.d:1]

bounds.fail19:                                    ; preds = %forbody12
  call void @_d_arraybounds({ i64, i8* } { i64 12, i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i32 0, i32 0) }, i32 0) #2, !dbg !57 ; [debug line = current.d:1]
  unreachable, !dbg !57                           ; [debug line = current.d:1]

forinc13:                                         ; preds = %bounds.ok23
  %42 = load i64, i64* %__key57, !dbg !57         ; [#uses = 1] [debug line = current.d:1]
  %43 = add i64 %42, 1, !dbg !57                  ; [#uses = 1] [debug line = current.d:1]
  store i64 %43, i64* %__key57, !dbg !57          ; [debug line = current.d:1]
  br label %forcond11

endfor14:                                         ; preds = %forcond11
  %44 = load { i64, x86_fp80* }, { i64, x86_fp80* }* %p27, !dbg !57 ; [#uses = 0] [debug line = current.d:1]
  %45 = load { i64, x86_fp80* }, { i64, x86_fp80* }* %p27, !dbg !57 ; [#uses = 1] [debug line = current.d:1]
  ret { i64, x86_fp80* } %45, !dbg !57            ; [debug line = current.d:1]
}

Note the ret in block endfor. If I haven't overlooked anything, everything below, i.e., the 2nd half of the function, cannot be reached and is totally superfluous.

@kinke
Copy link
Member

kinke commented Jul 23, 2017

Urgh. The special function is defined/codegen'd twice in the IR module, presumably due to 2 calls. And I seem to recall that if an existing function definition is found, all other definitions are simply appended to it (!).

@kinke
Copy link
Member

kinke commented Jul 23, 2017

Okay here our list of special druntime arrayop functions apparently isn't up to speed (isDruntimeArrayOp()). Nope, not available in druntime, and our list is up-to-date.

@JohanEngelen
Copy link
Member Author

Nice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants