What can cause llc to throw an error for instruction numbering?

I duplicated an instruction in llvm and changed its opcode by following the guide at Extending LLVM: Adding instructions, intrinsics, types, etc. — LLVM 16.0.0git documentation (Adding a new instruction) and then fixed the dependencies that caused an error when building. Now the modified llvm builds but throws but now throws the error:
llc: error: llc: check.ll:12:3: error: instruction expected to be numbered '%5'

  %4 = alloca i32, align 4

What changes/modification would cause this error to show up? I was thinking that SelectionDAGBuilder would cause this as it parses IR to an optimized version but not sure.

Hi Kaarthik,

llc: error: llc: check.ll:12:3: error: instruction expected to be numbered '%5'

  %4 = alloca i32, align 4

What changes/modification would cause this error to show up? I was thinking that SelectionDAGBuilder would cause this as it parses IR to an optimized version but not sure.

I think only the IR parser (lib/AsmParser/LLParser.cpp) produces that
error, which is well before anything in SelectionDAG runs.

Did you maybe intend to create an instruction that doesn't produce a
value (like "store" for example) but start off by copying one that did
produce a value? In that case, if your IR was really

    ...
    %3 = ...
    my_shiny_inst i32 %a, %b
    %4 = alloca i32
    ...

then during parsing LLVM will have decided that my_shiny_inst really
produced %4 (it wouldn't complain about "%4 =" being missing at that
point), but when the next instruction claimed to be %4 it would
produce the error you're describing.

Obviously the same situation could occur if your instruction really
does produce a value but you either intentionally or accidentally
omitted the "%4 =" in your test-case IR.

Cheers.

Tim.

Hi Tim,
Thank you for that. I was just trying to replicate the branch instruction under a new opcode, so I don’t think that returns a value. Plus the code I was testing out didn’t have a br or my newly added instruction but it still threw that error at me. Here’s the IR code I tested:
; ModuleID = ‘cc.c’
source_filename = “cc.c”
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128”
target triple = "x86_64-pc-linux-gnu”

; Function Attrs: noinline nounwind optnone uwtable
define i32 @main(i32, i8**) #0 {
  %3 = alloca i32, align 4
  %4 = alloca i8**, align 8
  store i32 %0, i32* %3, align 4
  store i8** %1, i8*** %4, align 8
  ret i32 0
}

attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "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-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float”=“false” }

!llvm.module.flags = !{!0}
!llvm.ident = !{!1}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)”}

I tested a longer IR code and if I fixed one of the instruction number to the expected one (say from %4 to %5), it tells me that the following line’s instruction number must be the nest odd number (that %5 should be %7). I am guessing that my modification is causing a value to be produced after each allocation instruction, would that still be under LLParser?

Thank you,
Kaarthik.

I think so. The parsing code is the first thing run on any IR, and
produces the internal representation everything else might use. So
there's just not really any other part of LLVM that could be involved.

The code you're looking for is in the function "SetInstName", and its
diagnostics seem to be derived directly from NumberedVals.size(). So
if it was me I'd be looking for two calls to SetInstName per
instruction, or maybe an out-of-band push to that variable.

Obviously I can't see what code you've written, but it might be worth
double checking any switch statements you've modified to make sure you
haven't left a fallthrough where it shouldn't be. That's the kind of
mistake I could see causing this.

Cheers.

Tim.

The problem is that there are some unnamed values in the listing, that are not explicitly printed. In reality you have

define i32 @main(i32 %0, i8** %1) #0 {

%2:

%3 = alloca i32, align 4

%4 = alloca i8**, align 8

store i32 %0, i32* %3, align 4

store i8** %1, i8*** %4, align 8

ret i32 0

}

Unnamed values are numbered from %0, and the numbers must be consecutive integers. Producing unnamed values is generally a bad idea for the reasons you’re experiencing. You can always run the ll file through “opt -instnamer” (e.g. opt -instnamer -S < inp.ll > out.ll), and that will rename all instructions (including giving names to the unnamed ones).

I don't think that works as a complete explanation, but it does
strongly suggest another avenue to investigate: what if LLVM is
starting a new basic block after every instruction for some reason?
Then LLVM would think it had

    define i32 @main(i32 %, i8** %1) {
     %2:
       %3 = alloca i32, align 4
     %4:
       %5 = alloca i8**, align 8
     %6:
        ...

Watching NumberedVals would still reveal this (I think), but not
SetInstName. And it would suggest looking at any extra code that might
affect when LLVM starts a new block.

Cheers.

Tim.

Thank you for that suggestion, but I tried opt -instnamer <file.ll> and it threw that same error unfortunately (for running opt -instnamer)

Regards,
Kaarthik.

Thank you for pointing that out Tim! I am going over the SetInstName function and about to edit the file to print out NumberedVals. I’ll also see if any of my modifications affect when LLVM starts a new block.

Regards,
Kaarthik.