3

I'm trying to initialize a constant vector of ones using LLVM IR as a starting point to familiarize myself with the vector operations supported by various targets. I have the following simple main function defined:

target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc19.31.31104"

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i64 @main() #0 {  
  %one = <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
  %i = bitcast <8 x i8> %one to i64
  ret i64 %i
}

The line %one = <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> gives a compile error from clang 13.0.1:

error: expected instruction opcode
%one = <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
       ^

No idea what the problem is, as the docs list in the example for the freeze instruction the following code:

; example with vectors
%v = <2 x i32> <i32 undef, i32 poison>
%a = extractelement <2 x i32> %v, i32 0    ; undef
%b = extractelement <2 x i32> %v, i32 1    ; poison
%add = add i32 %a, %a                      ; undef

which appears to use the same format for vector initialization that I'm using. I've also tried adding constant after the = sign but this yields the same error. The documentation for vector types describes constants using this format as well. For reference, I'm using the following command-line arguments with clang:

clang test.ll -o test.exe

Any idea why clang is having trouble understanding this code? I can't figure out what opcode it is expecting.

hatch22
  • 797
  • 6
  • 18

1 Answers1

4

Constant literals can not be assigned to variables and have to be specified directly:

%i = bitcast <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> to i64

You could "assign" constant by wrapping it in a dummy operation:

%one = add <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>, zeroinitializer
yugr
  • 19,769
  • 3
  • 51
  • 96
  • Out of curiosity, do you or anyone else know why this is the case, given that the documentation strongly suggests this should be possible, and even gives examples to that effect? – hatch22 Mar 14 '22 at 12:56
  • This might have worked in the past. I suggest to report an error in documentation to LLVM developers. – yugr Mar 14 '22 at 13:17
  • 2
    "%name = constant" was never valid LLVM IR. I think the example was in pseudocode. If you attempt to create the same Constant twice in LLVM, it will return the same llvm::Constant pointer. Constants (except `GlobalValue`s) can't have names. In the text format this means that to get multiple references to the same constant you must write out the full constant every time it's used. I think the authors of the example text for `freeze` thought it was clearer to give their undef a name even though it isn't actually valid syntax. Maybe they could make it clearer with `; Suppose: %w = i32 undef`. – Nick Lewycky Mar 15 '22 at 19:14