================
@@ -1674,7 +1674,30 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
                                                    mlir::ValueRange{a, b, c}));
   }
   case Builtin::BI__builtin_elementwise_add_sat:
-  case Builtin::BI__builtin_elementwise_sub_sat:
+  case Builtin::BI__builtin_elementwise_sub_sat: {
+    // cir.add/cir.sub do not model i1 arithmetic, so a bool-element
+    // saturating add/sub is not representable through the saturated op.
+    // Check the AST element type and bail before emitScalarExpr: an
+    // ext-vector-of-bool operand would otherwise hit the NYI bool-vector
+    // load, which returns a null value and would crash op0.getType().
+    QualType argTy = e->getArg(0)->getType();
+    if (const auto *vecTy = argTy->getAs<clang::VectorType>())
+      argTy = vecTy->getElementType();
+    if (argTy->isBooleanType()) {
+      cgm.errorNYI(e->getSourceRange(),
+                   "saturating add/sub on a boolean operand");
+      return RValue::get(nullptr);
+    }
+    mlir::Location loc = getLoc(e->getExprLoc());
----------------
adams381 wrote:

Dropped the unwrap -- the guard is just `isBooleanType() || 
isExtVectorBoolType()` now. After the emits I assert 
`isIntOrVectorOfIntType(op0)` to match classic's int/int-vector check.

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

Reply via email to