================
@@ -279,6 +285,102 @@ static mlir::Value emitX86MaskTest(CIRGenBuilderTy 
&builder, mlir::Location loc,
                              mlir::ValueRange{lhsVec, rhsVec});
 }
 
+// TODO: The cgf parameter should be removed when all the NYI cases are 
implemented.
+static std::optional<mlir::Value> emitX86MaskedCompareResult(CIRGenFunction 
&cgf, CIRGenBuilderTy &builder,
+                                              mlir::Value cmp, unsigned 
numElts,
+                                              mlir::Value maskIn,
+                                              mlir::Location loc) {
+  if (maskIn) {
+    cgf.cgm.errorNYI(loc, "emitX86MaskedCompareResult");
+    return {};
+  }
+  if (numElts < 8) {
+    llvm::SmallVector<mlir::Attribute> indices;
+    mlir::Type i64Ty = builder.getSInt64Ty();
+
+    for (unsigned i = 0; i != numElts; ++i)
+      indices.push_back(cir::IntAttr::get(i64Ty, i));
+    for (unsigned i = numElts; i != 8; ++i)
+      indices.push_back(cir::IntAttr::get(i64Ty, i % numElts + numElts));
+
+    // This should shuffle between cmp (first vector) and null (second vector)
+    mlir::Value nullVec = builder.getNullValue(cmp.getType(), loc);
+    cmp = builder.createVecShuffle(loc, cmp, nullVec, indices);
+  }
+  return builder.createBitcast(
+      cmp, builder.getUIntNTy(std::max(numElts, 8U)));
+}
+
+// TODO: The cgf parameter should be removed when all the NYI cases are 
implemented.
+static std::optional<mlir::Value> emitX86MaskedCompare(CIRGenFunction &cgf, 
CIRGenBuilderTy &builder,
+                                        unsigned cc, bool isSigned,
+                                        ArrayRef<mlir::Value> ops,
+                                        mlir::Location loc) {
+  assert((ops.size() == 2 || ops.size() == 4) &&
+         "Unexpected number of arguments");
+  unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getSize();
+  mlir::Value cmp;
+
+  if (cc == 3) {
+    cgf.cgm.errorNYI(loc, "emitX86MaskedCompare: cc == 3");
+    return {};
+  } else if (cc == 7) {
+    cgf.cgm.errorNYI(loc, "emitX86MaskedCompare cc == 7");
+    return {};
+  } else {
+    cir::CmpOpKind pred;
+    switch (cc) {
+    default:
+      llvm_unreachable("Unknown condition code");
+    case 0:
+      pred = cir::CmpOpKind::eq;
+      break;
+    case 1:
+      pred = cir::CmpOpKind::lt;
+      break;
+    case 2:
+      pred = cir::CmpOpKind::le;
+      break;
+    case 4:
+      pred = cir::CmpOpKind::ne;
+      break;
+    case 5:
+      pred = cir::CmpOpKind::ge;
+      break;
+    case 6:
+      pred = cir::CmpOpKind::gt;
+      break;
+    }
+
+    auto resultTy = cir::VectorType::get(builder.getSIntNTy(1), numElts);
+    cmp = cir::VecCmpOp::create(builder, loc, resultTy, pred, ops[0],
+                                ops[1]);
+  }
+
+  mlir::Value maskIn;
+  if (ops.size() == 4)
+    maskIn = ops[3];
+
+  return emitX86MaskedCompareResult(cgf, builder, cmp, numElts, maskIn, loc);
+}
+
+// TODO: The cgf parameter should be removed when all the NYI cases are 
implemented.
+static std::optional<mlir::Value> emitX86ConvertToMask(CIRGenFunction &cgf, 
CIRGenBuilderTy &builder,
+                                        mlir::Value in, mlir::Location loc) {
+  cir::ConstantOp zero = builder.getNullValue(in.getType(), loc);
+  return emitX86MaskedCompare(cgf, builder, 1, true, {in, zero}, loc);
+}
+
+
+static std::optional<mlir::Value> emitX86SExtMask(CIRGenBuilderTy &builder,
+                                  mlir::Value op,
+                                  mlir::Type dstTy, mlir::Location loc) {
+  unsigned numberOfElements = cast<cir::VectorType>(dstTy).getSize();
+  mlir::Value mask = getMaskVecValue(builder, loc, op, numberOfElements);
----------------
andykaylor wrote:

We have a problem here. Currently, `getMaskVecValue` creates a vector of i1 
like this: `!cir.vector<32 x !cir.int<u, 1>>`. Because we made the i1 type 
unsigned there, it's going to get zero extended by the cast below. In general, 
I find the idea of pretending that an i1 value has a sign-bit to be very 
dubious, but in this particular case we explicitly need the sign-extending 
behavior. So, we either need to change `getMaskVecValue` to return a signed i1 
vector, or we need to cast it as such here. The former is probably best. 
Ideally, it would be a vector of signless i1, but we don't do signless types in 
CIR.

https://github.com/llvm/llvm-project/pull/171694
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to