LLC Version 3.8 : Unsupported library call operation for a mul instruction

Hello List,

I am on the hook to instrument a piece of legacy LLVM IR code, and then we are planning to feed to the SeaHorn framework for some model checking tasks.

After the instrumentation, I tried to use llc (version 3.9) to compile the IR code, and it works fine. However, when I try to use llc (version 3.8.1, the default llvm version of SeaHorn) to compile the IR code, it shows the following error:

LLVM ERROR: Unsupported library call operation!

I tried to do some “delta debugging” and eventually locate the buggy line of the code. So as shown below, the following code cause llc (version 3.8.1) throws the “Unsupported library call operation” issue, but it works fine for llc version 3.9.

  %20 = call i256 @llvm.bswap.i256(i256 %msg.value)
  %21 = mul i256 %20, 190

I tried to tweak the buggy lines into the following code, and it can also pass the compilation:

  %20 = call i256 @llvm.bswap.i256(i256 %msg.value)
  %21 = add i256 %20, 190

This seems really wired to me… Any idea on that? Thank you!

Best,

Irene

Hi Irene,
I’m absolutely not but have you tried to compile your .c project using -O3 -march=native and see that call to bswap is not present after? Are we sure that bswap was present in version 3.8.1?

Thanks

Hi Alberto,

Thanks for your reply. So this piece of code is a legacy IIVM IR code which is not compiled from C project… I don’t even know which clang they use to produce the IR.

But on the other hand, I tried to collect those related code pieces and put them into a simple hello world function, it works fine (attached below). So it seems quite wired to me…

Also, I made a mistake in previous email. It should be llc version 3.8.1, not 3.8.0.

Irene.

    ; ModuleID = 'hello.c'
    target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
    target triple = "x86_64-unknown-linux-gnu"

    @.str = private unnamed_addr constant [13 x i8] c"Hello World\0A\00", align 1

    ; Function Attrs: nounwind uwtable
    define i32 @main() #0 {
      %1 = alloca i32, align 4
      store i32 0, i32* %1, align 4
      %2 = add i256 0, 1
      %3 = call i256 @llvm.bswap.i256(i256 %2)
      %4 = mul i256 %3, 190
      %5 = call i256 @test.udiv.i256(i256 %4, i256 100)
      %6 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i32 0, i32 0))
      ret i32 0
    }

     ; Function Attrs: nounwind readnone
declare i256 @llvm.bswap.i256(i256) #1

declare i256 @llvm.ctlz.i256(i256, i1) #1

define private <2 x i256> @test.udivrem.i256(i256 %x, i256 %y) {
Entry:
  %0 = icmp ule i256 %y, %x
  br i1 %0, label %Main, label %Return

Main:                                             ; preds = %Entry
  %y.lz = call i256 @llvm.ctlz.i256(i256 %y, i1 true)
  %r.lz = call i256 @llvm.ctlz.i256(i256 %x, i1 true)
  %i0 = sub nuw i256 %y.lz, %r.lz
  %1 = shl i256 %y, %i0
  br label %Loop

Loop:                                             ; preds = %Continue, %Main
  %y.phi = phi i256 [ %1, %Main ], [ %8, %Continue ]
  %r.phi = phi i256 [ %x, %Main ], [ %r1, %Continue ]
  %i.phi = phi i256 [ %i0, %Main ], [ %6, %Continue ]
  %q.phi = phi i256 [ 0, %Main ], [ %7, %Continue ]
  %2 = sub nuw i256 %r.phi, %y.phi
  %3 = or i256 %q.phi, 1
  %4 = icmp uge i256 %r.phi, %y.phi
  %r1 = select i1 %4, i256 %2, i256 %r.phi
  %q = select i1 %4, i256 %3, i256 %q.phi
  %5 = icmp eq i256 %i.phi, 0
  br i1 %5, label %Return, label %Continue

Continue:                                         ; preds = %Loop
  %6 = sub nuw i256 %i.phi, 1
  %7 = shl i256 %q, 1
  %8 = lshr i256 %y.phi, 1
  br label %Loop

Return:                                           ; preds = %Loop, %Entry
  %q.ret = phi i256 [ 0, %Entry ], [ %q, %Loop ]
  %r.ret = phi i256 [ %x, %Entry ], [ %r1, %Loop ]
  %ret0 = insertelement <2 x i256> undef, i256 %q.ret, i64 0
  %ret = insertelement <2 x i256> %ret0, i256 %r.ret, i64 1
  ret <2 x i256> %ret
}

define private i256 @test.udiv.i256(i256 %x, i256 %y) {
  %1 = call <2 x i256> @test.udivrem.i256(i256 %x, i256 %y)
  %2 = extractelement <2 x i256> %1, i64 0
  ret i256 %2
}

declare i32 @printf(i8*, ...) #1

attributes #0 = { nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
@
attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.ident = !{!0}

!0 = !{!"clang version 3.8.0 (tags/RELEASE_380/final)"}