Bug report : vector.extract_element

Hi people,

I think I just encountered a bug. On the latest version of the compiler (commit 396e7f454893e24969bb989fe89aa028e2ea1693), I use this command line :
mlir-opt demo/sandbox/vector.mlir --convert-std-to-llvm

On this file :

func @test() -> (i1) {
    %c0 = constant 3 : index
    br ^bb1(%c0: index)
  ^bb1(%i: index):
    %cst = constant dense<[true, false, true, true, true, false]> : vector<6xi1>
    %r = extract_element %cst[%i] : vector<6xi1>
    return %r: i1
}

And get this error message :

vector.mlir:15:10: error: 'std.extract_element' op operand #0 must be vector of any type values or tensor of any type values, but got '!llvm.vec<6 x i1>'
    %r = extract_element %cst[%i] : vector<6xi1>
         ^
vector.mlir:15:10: note: see current operation: %3 = "std.extract_element"(%2, %1) : (!llvm.vec<6 x i1>, !llvm.i64) -> i1

There is no problem when the file just contains :

func @test() -> (i1) {
  %c0 = constant 3 : index
  %cst = constant dense<[true, false, true, true, true, false]> : vector<6xi1>
  %r = extract_element %cst[%c0] : vector<6xi1>
  return %r: i1
}

So the problem just occurs when the BranchOp is present.

Of course, the following example using scf.if is buggy too :

func @test2(%in: i1) -> (i1) {
  %cst = constant dense<[true, false, true, true, true, false]> : vector<6xi1>
  %v = scf.if %in -> (index) {
    %c0 = constant 3 : index
    scf.yield %c0: index
  } else {
    %c1 = constant 4 : index
    scf.yield %c1: index
  }
  %r = extract_element %cst[%v] : vector<6xi1>
  return %r: i1
}

Regards,

qaco

Please note that your title should mention "std.extract_element’. The prefix “vector” implies Vector dialect, and the vector operation works for me (with convert-vector-to-llvm). The test without the branch constant folds into “true”.

func @test1() -> (i1) {
  %c0 = constant 3 : i32
  br ^bb1(%c0: i32)
^bb1(%i: i32):
  %cst = constant dense<[true, false, true, true, true, false]> : vector<6xi1>
  %r = vector.extractelement %cst[%i:i32] : vector<6xi1>
  return %r: i1
}

// Lowers to:

  llvm.func @test1() -> !llvm.i1 {
    %0 = llvm.mlir.constant(3 : i32) : !llvm.i32
    %1 = llvm.mlir.constant(dense<[true, false, true, true, true, false]> : vector<6xi1>) : !llvm.vec<6 x i1>
    llvm.br ^bb1(%0 : !llvm.i32)
  ^bb1(%2: !llvm.i32):  // pred: ^bb0
    %3 = llvm.extractelement %1[%2 : !llvm.i32] : !llvm.vec<6 x i1>
    llvm.return %3 : !llvm.i1
  }
1 Like

That’s right. Thank you very much.