[llvm-dev] Difficulty matching zext in tablegen/SelectionDAG (was: [RFC] Carry-less multiplication)

Shawn Landden via llvm-dev
2020-07-19T15:23:50Z

In trying to implement my RFC I ran into difficulty selecting
zero-extends, either in a custom lowering, or in tablegen.

For example, Power 8 has <2 x i32> -> <2 x i64>, <4 x i16>
-> <4 x
i32>, <1 x i64> -> <1 x i128> instructions.

And the generated MIR looks different for the different cases:

LLVM ERROR: Cannot select: t10: v2i64 = clmul t36, t35
  t36: v2i64 = bitcast t33
    t33: v16i8 vector_shuffle<0,1,2,3,16,17,18,19,4,5,6,7,20,21,22,23>
t32, t29
      t32: v16i8 = bitcast t2
        t2: v4i32,ch = CopyFromReg t0, Register:v4i32 %0
          t1: v4i32 = Register %0
      t29: v16i8 = bitcast t19
        t19: v4i32 = BUILD_VECTOR Constant:i32<0>, Constant:i32<0>,
Constant:i32<0>, Constant:i32<0>
          t18: i32 = Constant<0>
          t18: i32 = Constant<0>
          t18: i32 = Constant<0>
          t18: i32 = Constant<0>
  t35: v2i64 = bitcast t30
    t30: v16i8 vector_shuffle<0,1,2,3,16,17,18,19,4,5,6,7,20,21,22,23>
t28, t29
      t28: v16i8 = bitcast t4
        t4: v4i32,ch = CopyFromReg t0, Register:v4i32 %1
          t3: v4i32 = Register %1
      t29: v16i8 = bitcast t19
        t19: v4i32 = BUILD_VECTOR Constant:i32<0>, Constant:i32<0>,
Constant:i32<0>, Constant:i32<0>
          t18: i32 = Constant<0>
          t18: i32 = Constant<0>
          t18: i32 = Constant<0>
          t18: i32 = Constant<0>

LLVM ERROR: Cannot select: t9: v1i128 = clmul t24, t28
  t24: v1i128 = bitcast t23
    t23: v2i64 = BUILD_VECTOR t2, Constant:i64<0>
      t2: i64,ch = CopyFromReg t0, Register:i64 %0
        t1: i64 = Register %0
      t13: i64 = Constant<0>
  t28: v1i128 = bitcast t27
    t27: v2i64 = BUILD_VECTOR t4, Constant:i64<0>
      t4: i64,ch = CopyFromReg t0, Register:i64 %1
        t3: i64 = Register %1
      t13: i64 = Constant<0>


I might be able to use demandedBits in a custom rule, but it sure
would nice if zext actually worked, like it would in LLVM-IR. The
burden of learning totally distinct tools for different levels of the
compiler (in addition to the assembly of the target) is quite
annoying.