================
@@ -469,8 +465,28 @@ static mlir::Value emitCommonNeonSISDBuiltinExpr(
auto [funcResTy, argTypes] = deriveNeonSISDIntrinsicOperandTypes(
cgf, info.TypeModifier, arg0Ty, resultTy, ops);
- return emitNeonCall(cgf.cgm, builder, std::move(argTypes), ops, llvmIntrName,
- funcResTy, loc);
+ // Scalar operands feeding a vector `argType` (e.g. vqsubb_s8, which has no
+ // scalar overload) are splatted into lane 0 of a poison vector.
+ for (unsigned i = 0, e = ops.size(); i != e; ++i) {
+ auto vecArgTy = mlir::dyn_cast<cir::VectorType>(argTypes[i]);
+ if (vecArgTy && !mlir::isa<cir::VectorType>(ops[i].getType()) &&
+ cgf.cgm.getDataLayout().getTypeSizeInBits(ops[i].getType()) !=
+ cgf.cgm.getDataLayout().getTypeSizeInBits(vecArgTy)) {
+ mlir::Value poison =
+ builder.getConstant(loc, cir::PoisonAttr::get(vecArgTy));
+ ops[i] = builder.createInsertElement(loc, poison, ops[i], /*idx=*/0);
+ }
+ }
+
+ mlir::Value result = emitNeonCall(cgf.cgm, builder, std::move(argTypes), ops,
+ llvmIntrName, funcResTy, loc);
+
+ // Recover a scalar result from a wider vector intrinsic result via lane 0.
+ if (auto resVecTy = mlir::dyn_cast<cir::VectorType>(result.getType());
+ resVecTy && cgf.cgm.getDataLayout().getTypeSizeInBits(resultTy) <
+ cgf.cgm.getDataLayout().getTypeSizeInBits(resVecTy))
+ return builder.createExtractElement(loc, result, /*idx=*/0);
+ return result;
----------------
banach-space wrote:
While these changes make sense to me, I find them rather counter-intuitive -
_why_ do we need `cir.vec.insert` and `cir.vec.extract`? I know that you are
following ARM.cpp, but that code is also a bit non-intuitive :)
I would add a few more comments. My understanding of what is happening here is
that:
* An SISD intrinsic is lowered to (and modelled with) a vector builtin, hence
`cir.vec.insert` and `cir.vec.extract`.
Is this consistent with your understanding?
Also, an equivalent of the following assert would be helpful:
https://github.com/llvm/llvm-project/blob/bb6868abb8dd6f8ef7130ed2c81cf538793547c6/clang/lib/CodeGen/TargetBuiltins/ARM.cpp?plain=1#L1099-L1101
[nit] "splat" to me means "broadcast" (i.e. make all vector elements equal). In
this case, from what I can tell, there is no "splatting" :)
Thank you :)
https://github.com/llvm/llvm-project/pull/207189
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits