Skip to content

Commit 329aca9

Browse files
authored
[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 1b97f92 commit 329aca9

File tree

7 files changed

+80
-6
lines changed

7 files changed

+80
-6
lines changed

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4331,8 +4331,8 @@ def SqrtOp : UnaryFPToFPBuiltinOp<"sqrt", "SqrtOp">;
43314331
def TruncOp : UnaryFPToFPBuiltinOp<"trunc", "FTruncOp">;
43324332

43334333
def AbsOp : CIR_Op<"abs", [Pure, SameOperandsAndResultType]> {
4334-
let arguments = (ins PrimitiveSInt:$src, UnitAttr:$poison);
4335-
let results = (outs PrimitiveSInt:$result);
4334+
let arguments = (ins CIR_AnySignedIntOrVecOfSignedInt:$src, UnitAttr:$poison);
4335+
let results = (outs CIR_AnySignedIntOrVecOfSignedInt:$result);
43364336
let summary = [{
43374337
libc builtin equivalent abs, labs, llabs
43384338

@@ -4345,6 +4345,7 @@ def AbsOp : CIR_Op<"abs", [Pure, SameOperandsAndResultType]> {
43454345
```mlir
43464346
%0 = cir.const #cir.int<-42> : s32i
43474347
%1 = cir.abs %0 poison : s32i
4348+
%2 = cir.abs %3 : !cir.vector<!s32i x 4>
43484349
```
43494350
}];
43504351
let assemblyFormat = "$src ( `poison` $poison^ )? `:` type($src) attr-dict";

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ class StructType
184184

185185
bool isAnyFloatingPointType(mlir::Type t);
186186
bool isFPOrFPVectorTy(mlir::Type);
187+
bool isIntOrIntVectorTy(mlir::Type);
187188
} // namespace cir
188189

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

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

Lines changed: 17 additions & 0 deletions
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

Lines changed: 3 additions & 0 deletions
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

Lines changed: 16 additions & 3 deletions
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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,7 @@ bool cir::isAnyFloatingPointType(mlir::Type t) {
828828
}
829829

830830
//===----------------------------------------------------------------------===//
831-
// Floating-point and Float-point Vecotr type helpers
831+
// Floating-point and Float-point Vector type helpers
832832
//===----------------------------------------------------------------------===//
833833

834834
bool cir::isFPOrFPVectorTy(mlir::Type t) {
@@ -840,6 +840,18 @@ bool cir::isFPOrFPVectorTy(mlir::Type t) {
840840
return isAnyFloatingPointType(t);
841841
}
842842

843+
//===----------------------------------------------------------------------===//
844+
// CIR Integer and Integer Vector type helpers
845+
//===----------------------------------------------------------------------===//
846+
847+
bool cir::isIntOrIntVectorTy(mlir::Type t) {
848+
849+
if (isa<cir::VectorType>(t)) {
850+
return isa<cir::IntType>(mlir::dyn_cast<cir::VectorType>(t).getEltType());
851+
}
852+
return isa<cir::IntType>(t);
853+
}
854+
843855
//===----------------------------------------------------------------------===//
844856
// ComplexType Definitions
845857
//===----------------------------------------------------------------------===//
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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+
7+
typedef int vint4 __attribute__((ext_vector_type(4)));
8+
9+
void test_builtin_elementwise_abs(vint4 vi4, int i, float f, double d) {
10+
// CIR-LABEL: test_builtin_elementwise_abs
11+
// LLVM-LABEL: test_builtin_elementwise_abs
12+
// CIR: {{%.*}} = cir.fabs {{%.*}} : !cir.float
13+
// LLVM: {{%.*}} = call float @llvm.fabs.f32(float {{%.*}})
14+
f = __builtin_elementwise_abs(f);
15+
16+
// CIR: {{%.*}} = cir.fabs {{%.*}} : !cir.double
17+
// LLVM: {{%.*}} = call double @llvm.fabs.f64(double {{%.*}})
18+
d = __builtin_elementwise_abs(d);
19+
20+
// CIR: {{%.*}} = cir.abs {{%.*}} : !cir.vector<!s32i x 4>
21+
// LLVM: {{%.*}} = call <4 x i32> @llvm.abs.v4i32(<4 x i32> {{%.*}}, i1 false)
22+
vi4 = __builtin_elementwise_abs(vi4);
23+
24+
// CIR: {{%.*}} = cir.abs {{%.*}} : !s32
25+
// LLVM: {{%.*}} = call i32 @llvm.abs.i32(i32 {{%.*}}, i1 false)
26+
i = __builtin_elementwise_abs(i);
27+
}

0 commit comments

Comments
 (0)