Skip to content

Commit 33d8963

Browse files
ghehglanza
authored andcommitted
[CIR][CIRGen][Builtin] Support __builtin_elementwise_abs and extend AbsOp to take vector input (#1099)
Extend AbsOp to take vector of int input. With it, we can support __builtin_elementwise_abs. We should in the next PR extend FpUnaryOps to support vector type input so we won't have blocker to implement all elementwise builtins completely. Now just temporarily have missingFeature `fpUnaryOPsSupportVectorType`. Currently, int type UnaryOp support vector type. FYI: [clang's documentation about elementwise builtins](https://clang.llvm.org/docs/LanguageExtensions.html#vector-builtins)
1 parent fa0598a commit 33d8963

File tree

7 files changed

+81
-6
lines changed

7 files changed

+81
-6
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

+3-2
Original file line numberDiff line numberDiff line change
@@ -4340,8 +4340,8 @@ def SqrtOp : UnaryFPToFPBuiltinOp<"sqrt", "SqrtOp">;
43404340
def TruncOp : UnaryFPToFPBuiltinOp<"trunc", "FTruncOp">;
43414341

43424342
def AbsOp : CIR_Op<"abs", [Pure, SameOperandsAndResultType]> {
4343-
let arguments = (ins PrimitiveSInt:$src, UnitAttr:$poison);
4344-
let results = (outs PrimitiveSInt:$result);
4343+
let arguments = (ins CIR_AnySignedIntOrVecOfSignedInt:$src, UnitAttr:$poison);
4344+
let results = (outs CIR_AnySignedIntOrVecOfSignedInt:$result);
43454345
let summary = [{
43464346
libc builtin equivalent abs, labs, llabs
43474347

@@ -4354,6 +4354,7 @@ def AbsOp : CIR_Op<"abs", [Pure, SameOperandsAndResultType]> {
43544354
```mlir
43554355
%0 = cir.const #cir.int<-42> : s32i
43564356
%1 = cir.abs %0 poison : s32i
4357+
%2 = cir.abs %3 : !cir.vector<!s32i x 4>
43574358
```
43584359
}];
43594360
let assemblyFormat = "$src ( `poison` $poison^ )? `:` type($src) attr-dict";

clang/include/clang/CIR/Dialect/IR/CIRTypes.h

+1
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ class StructType
182182

183183
bool isAnyFloatingPointType(mlir::Type t);
184184
bool isFPOrFPVectorTy(mlir::Type);
185+
bool isIntOrIntVectorTy(mlir::Type);
185186
} // namespace cir
186187

187188
mlir::ParseResult parseAddrSpaceAttribute(mlir::AsmParser &p,

clang/include/clang/CIR/Dialect/IR/CIRTypes.td

+17
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ def CIR_IntType : CIR_Type<"Int", "int",
6060
bool isPrimitive() const {
6161
return isValidPrimitiveIntBitwidth(getWidth());
6262
}
63+
bool isSignedPrimitive() const {
64+
return isPrimitive() && isSigned();
65+
}
6366

6467
/// Returns a minimum bitwidth of cir::IntType
6568
static unsigned minBitwidth() { return 1; }
@@ -538,8 +541,22 @@ def IntegerVector : Type<
538541
]>, "!cir.vector of !cir.int"> {
539542
}
540543

544+
// Vector of signed integral type
545+
def SignedIntegerVector : Type<
546+
And<[
547+
CPred<"::mlir::isa<::cir::VectorType>($_self)">,
548+
CPred<"::mlir::isa<::cir::IntType>("
549+
"::mlir::cast<::cir::VectorType>($_self).getEltType())">,
550+
CPred<"::mlir::cast<::cir::IntType>("
551+
"::mlir::cast<::cir::VectorType>($_self).getEltType())"
552+
".isSignedPrimitive()">
553+
]>, "!cir.vector of !cir.int"> {
554+
}
555+
541556
// Constraints
542557
def CIR_AnyIntOrVecOfInt: AnyTypeOf<[CIR_IntType, IntegerVector]>;
558+
def CIR_AnySignedIntOrVecOfSignedInt: AnyTypeOf<
559+
[PrimitiveSInt, SignedIntegerVector]>;
543560

544561
// Pointer to Arrays
545562
def ArrayPtr : Type<

clang/include/clang/CIR/MissingFeatures.h

+3
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,9 @@ struct MissingFeatures {
328328

329329
//-- Other missing features
330330

331+
// We need to extend fpUnaryOPs to support vector types.
332+
static bool fpUnaryOPsSupportVectorType() { return false; }
333+
331334
// We need to track the parent record types that represent a field
332335
// declaration. This is necessary to determine the layout of a class.
333336
static bool fieldDeclAbstraction() { return false; }

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

+16-3
Original file line numberDiff line numberDiff line change
@@ -1255,9 +1255,22 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
12551255
case Builtin::BI__builtin_nondeterministic_value:
12561256
llvm_unreachable("BI__builtin_nondeterministic_value NYI");
12571257

1258-
case Builtin::BI__builtin_elementwise_abs:
1259-
llvm_unreachable("BI__builtin_elementwise_abs NYI");
1260-
1258+
case Builtin::BI__builtin_elementwise_abs: {
1259+
mlir::Type cirTy = ConvertType(E->getArg(0)->getType());
1260+
bool isIntTy = cir::isIntOrIntVectorTy(cirTy);
1261+
if (!isIntTy) {
1262+
if (cir::isAnyFloatingPointType(cirTy)) {
1263+
return emitUnaryFPBuiltin<cir::FAbsOp>(*this, *E);
1264+
}
1265+
assert(!MissingFeatures::fpUnaryOPsSupportVectorType());
1266+
llvm_unreachable("unsupported type for BI__builtin_elementwise_abs");
1267+
}
1268+
mlir::Value arg = emitScalarExpr(E->getArg(0));
1269+
auto call = getBuilder().create<cir::AbsOp>(getLoc(E->getExprLoc()),
1270+
arg.getType(), arg, false);
1271+
mlir::Value result = call->getResult(0);
1272+
return RValue::get(result);
1273+
}
12611274
case Builtin::BI__builtin_elementwise_acos:
12621275
llvm_unreachable("BI__builtin_elementwise_acos NYI");
12631276
case Builtin::BI__builtin_elementwise_asin:

clang/lib/CIR/Dialect/IR/CIRTypes.cpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,7 @@ bool cir::isAnyFloatingPointType(mlir::Type t) {
740740
}
741741

742742
//===----------------------------------------------------------------------===//
743-
// Floating-point and Float-point Vecotr type helpers
743+
// Floating-point and Float-point Vector type helpers
744744
//===----------------------------------------------------------------------===//
745745

746746
bool cir::isFPOrFPVectorTy(mlir::Type t) {
@@ -752,6 +752,18 @@ bool cir::isFPOrFPVectorTy(mlir::Type t) {
752752
return isAnyFloatingPointType(t);
753753
}
754754

755+
//===----------------------------------------------------------------------===//
756+
// CIR Integer and Integer Vector type helpers
757+
//===----------------------------------------------------------------------===//
758+
759+
bool cir::isIntOrIntVectorTy(mlir::Type t) {
760+
761+
if (isa<cir::VectorType>(t)) {
762+
return isa<cir::IntType>(mlir::dyn_cast<cir::VectorType>(t).getEltType());
763+
}
764+
return isa<cir::IntType>(t);
765+
}
766+
755767
//===----------------------------------------------------------------------===//
756768
// ComplexType Definitions
757769
//===----------------------------------------------------------------------===//
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %clang_cc1 -triple aarch64-none-linux-android24 -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
3+
// RUN: %clang_cc1 -triple aarch64-none-linux-android24 -fclangir \
4+
// RUN: -emit-llvm %s -o %t.ll
5+
// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
6+
// XFAIL: *
7+
8+
typedef int vint4 __attribute__((ext_vector_type(4)));
9+
10+
void test_builtin_elementwise_abs(vint4 vi4, int i, float f, double d) {
11+
// CIR-LABEL: test_builtin_elementwise_abs
12+
// LLVM-LABEL: test_builtin_elementwise_abs
13+
// CIR: {{%.*}} = cir.fabs {{%.*}} : !cir.float
14+
// LLVM: {{%.*}} = call float @llvm.fabs.f32(float {{%.*}})
15+
f = __builtin_elementwise_abs(f);
16+
17+
// CIR: {{%.*}} = cir.fabs {{%.*}} : !cir.double
18+
// LLVM: {{%.*}} = call double @llvm.fabs.f64(double {{%.*}})
19+
d = __builtin_elementwise_abs(d);
20+
21+
// CIR: {{%.*}} = cir.abs {{%.*}} : !cir.vector<!s32i x 4>
22+
// LLVM: {{%.*}} = call <4 x i32> @llvm.abs.v4i32(<4 x i32> {{%.*}}, i1 false)
23+
vi4 = __builtin_elementwise_abs(vi4);
24+
25+
// CIR: {{%.*}} = cir.abs {{%.*}} : !s32
26+
// LLVM: {{%.*}} = call i32 @llvm.abs.i32(i32 {{%.*}}, i1 false)
27+
i = __builtin_elementwise_abs(i);
28+
}

0 commit comments

Comments
 (0)