Skip to content

Commit d331082

Browse files
ghehglanza
authored andcommitted
[CIR][CIRGen][Builtin][Neon] Lower neon_vrshr_n and vrshrq_n to llvm intrinsics (#1020)
In this PR, also changed `buildNeonShiftVector` to allow it generates negative shift values. When the shift value is negative, the shift amount vector is not used in any ShiftOp of IR (as they don't need sign to know shift direction), instead, it is just input argument to shift intrinsic function call.
1 parent 040070a commit d331082

File tree

3 files changed

+286
-142
lines changed

3 files changed

+286
-142
lines changed

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,6 @@ struct MissingFeatures {
172172
static bool volatileTypes() { return false; }
173173
static bool syncScopeID() { return false; }
174174

175-
// AArch64 Neon builtin related.
176-
static bool buildNeonShiftVector() { return false; }
177-
178175
// ABIInfo queries.
179176
static bool useTargetLoweringABIInfo() { return false; }
180177

clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp

Lines changed: 53 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2158,6 +2158,43 @@ static mlir::Value buildArmLdrexNon128Intrinsic(unsigned int builtinID,
21582158
}
21592159
}
21602160

2161+
/// Given a vector of unsigned int type `vecTy`, return a vector type of
2162+
/// signed int type with the same element type width and vector size.
2163+
static mlir::cir::VectorType getSignedVectorType(CIRGenBuilderTy &builder,
2164+
mlir::cir::VectorType vecTy) {
2165+
auto elemTy = mlir::cast<mlir::cir::IntType>(vecTy.getEltType());
2166+
elemTy = builder.getSIntNTy(elemTy.getWidth());
2167+
return mlir::cir::VectorType::get(builder.getContext(), elemTy,
2168+
vecTy.getSize());
2169+
}
2170+
2171+
/// Get integer from a mlir::Value that is an int constant or a constant op.
2172+
static int64_t getIntValueFromConstOp(mlir::Value val) {
2173+
auto constOp = mlir::cast<mlir::cir::ConstantOp>(val.getDefiningOp());
2174+
return (mlir::cast<mlir::cir::IntAttr>(constOp.getValue()))
2175+
.getValue()
2176+
.getSExtValue();
2177+
}
2178+
2179+
/// Build a constant shift amount vector of `vecTy` to shift a vector
2180+
/// Here `shitfVal` is a constant integer that will be splated into a
2181+
/// a const vector of `vecTy` which is the return of this function
2182+
static mlir::Value buildNeonShiftVector(CIRGenBuilderTy &builder,
2183+
mlir::Value shiftVal,
2184+
mlir::cir::VectorType vecTy,
2185+
mlir::Location loc, bool neg) {
2186+
int shiftAmt = getIntValueFromConstOp(shiftVal);
2187+
if (neg)
2188+
shiftAmt = -shiftAmt;
2189+
llvm::SmallVector<mlir::Attribute> vecAttr{
2190+
vecTy.getSize(),
2191+
// ConstVectorAttr requires cir::IntAttr
2192+
mlir::cir::IntAttr::get(vecTy.getEltType(), shiftAmt)};
2193+
mlir::cir::ConstVectorAttr constVecAttr = mlir::cir::ConstVectorAttr::get(
2194+
vecTy, mlir::ArrayAttr::get(builder.getContext(), vecAttr));
2195+
return builder.create<mlir::cir::ConstantOp>(loc, vecTy, constVecAttr);
2196+
}
2197+
21612198
mlir::Value buildNeonCall(CIRGenBuilderTy &builder,
21622199
llvm::SmallVector<mlir::Type> argTypes,
21632200
llvm::SmallVectorImpl<mlir::Value> &args,
@@ -2170,38 +2207,27 @@ mlir::Value buildNeonCall(CIRGenBuilderTy &builder,
21702207
assert(!MissingFeatures::buildConstrainedFPCall());
21712208
if (isConstrainedFPIntrinsic)
21722209
llvm_unreachable("isConstrainedFPIntrinsic NYI");
2173-
// TODO: Remove the following unreachable and call it in the loop once
2174-
// there is an implementation of buildNeonShiftVector
2175-
if (shift > 0)
2176-
llvm_unreachable("Argument shift NYI");
21772210

21782211
for (unsigned j = 0; j < argTypes.size(); ++j) {
21792212
if (isConstrainedFPIntrinsic) {
21802213
assert(!MissingFeatures::buildConstrainedFPCall());
21812214
}
21822215
if (shift > 0 && shift == j) {
2183-
assert(!MissingFeatures::buildNeonShiftVector());
2216+
args[j] = buildNeonShiftVector(
2217+
builder, args[j], mlir::cast<mlir::cir::VectorType>(argTypes[j]), loc,
2218+
rightshift);
21842219
} else {
21852220
args[j] = builder.createBitcast(args[j], argTypes[j]);
21862221
}
21872222
}
21882223
if (isConstrainedFPIntrinsic) {
21892224
assert(!MissingFeatures::buildConstrainedFPCall());
21902225
return nullptr;
2191-
} else {
2192-
return builder
2193-
.create<mlir::cir::IntrinsicCallOp>(
2194-
loc, builder.getStringAttr(intrinsicName), funcResTy, args)
2195-
.getResult();
21962226
}
2197-
}
2198-
2199-
/// Get integer from a mlir::Value that is an int constant or a constant op.
2200-
static int64_t getIntValueFromConstOp(mlir::Value val) {
2201-
auto constOp = mlir::cast<mlir::cir::ConstantOp>(val.getDefiningOp());
2202-
return (mlir::cast<mlir::cir::IntAttr>(constOp.getValue()))
2203-
.getValue()
2204-
.getSExtValue();
2227+
return builder
2228+
.create<mlir::cir::IntrinsicCallOp>(
2229+
loc, builder.getStringAttr(intrinsicName), funcResTy, args)
2230+
.getResult();
22052231
}
22062232

22072233
/// This function `buildCommonNeonCallPattern0` implements a common way
@@ -2229,23 +2255,6 @@ buildCommonNeonCallPattern0(CIRGenFunction &cgf, llvm::StringRef intrincsName,
22292255
return builder.createBitcast(res, resultType);
22302256
}
22312257

2232-
/// Build a constant shift amount vector of `vecTy` to shift a vector
2233-
/// Here `shitfVal` is a constant integer that will be splated into a
2234-
/// a const vector of `vecTy` which is the return of this function
2235-
static mlir::Value buildNeonShiftVector(CIRGenBuilderTy &builder,
2236-
mlir::Value shiftVal,
2237-
mlir::cir::VectorType vecTy,
2238-
mlir::Location loc, bool neg) {
2239-
int shiftAmt = getIntValueFromConstOp(shiftVal);
2240-
llvm::SmallVector<mlir::Attribute> vecAttr{
2241-
vecTy.getSize(),
2242-
// ConstVectorAttr requires cir::IntAttr
2243-
mlir::cir::IntAttr::get(vecTy.getEltType(), shiftAmt)};
2244-
mlir::cir::ConstVectorAttr constVecAttr = mlir::cir::ConstVectorAttr::get(
2245-
vecTy, mlir::ArrayAttr::get(builder.getContext(), vecAttr));
2246-
return builder.create<mlir::cir::ConstantOp>(loc, vecTy, constVecAttr);
2247-
}
2248-
22492258
/// Build ShiftOp of vector type whose shift amount is a vector built
22502259
/// from a constant integer using `buildNeonShiftVector` function
22512260
static mlir::Value buildCommonNeonShift(CIRGenBuilderTy &builder,
@@ -2343,6 +2352,15 @@ mlir::Value CIRGenFunction::buildCommonNeonBuiltinExpr(
23432352
: "llvm.aarch64.neon.sqrdmulh.lane",
23442353
resTy, getLoc(e->getExprLoc()));
23452354
}
2355+
case NEON::BI__builtin_neon_vrshr_n_v:
2356+
case NEON::BI__builtin_neon_vrshrq_n_v: {
2357+
return buildNeonCall(
2358+
builder, {vTy, isUnsigned ? getSignedVectorType(builder, vTy) : vTy},
2359+
ops, isUnsigned ? "llvm.aarch64.neon.urshl" : "llvm.aarch64.neon.srshl",
2360+
vTy, getLoc(e->getExprLoc()), false, /* not fp constrained op*/
2361+
1, /* second arg is shift amount */
2362+
true /* rightshift */);
2363+
}
23462364
case NEON::BI__builtin_neon_vshl_n_v:
23472365
case NEON::BI__builtin_neon_vshlq_n_v: {
23482366
mlir::Location loc = getLoc(e->getExprLoc());

0 commit comments

Comments
 (0)