Skip to content

Commit c5124be

Browse files
authored
[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 b4d4611 commit c5124be

File tree

3 files changed

+288
-142
lines changed

3 files changed

+288
-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
@@ -2160,6 +2160,43 @@ static mlir::Value buildArmLdrexNon128Intrinsic(unsigned int builtinID,
21602160
}
21612161
}
21622162

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

21802213
for (unsigned j = 0; j < argTypes.size(); ++j) {
21812214
if (isConstrainedFPIntrinsic) {
21822215
assert(!MissingFeatures::buildConstrainedFPCall());
21832216
}
21842217
if (shift > 0 && shift == j) {
2185-
assert(!MissingFeatures::buildNeonShiftVector());
2218+
args[j] = buildNeonShiftVector(
2219+
builder, args[j], mlir::cast<mlir::cir::VectorType>(argTypes[j]), loc,
2220+
rightshift);
21862221
} else {
21872222
args[j] = builder.createBitcast(args[j], argTypes[j]);
21882223
}
21892224
}
21902225
if (isConstrainedFPIntrinsic) {
21912226
assert(!MissingFeatures::buildConstrainedFPCall());
21922227
return nullptr;
2193-
} else {
2194-
return builder
2195-
.create<mlir::cir::IntrinsicCallOp>(
2196-
loc, builder.getStringAttr(intrinsicName), funcResTy, args)
2197-
.getResult();
21982228
}
2199-
}
2200-
2201-
/// Get integer from a mlir::Value that is an int constant or a constant op.
2202-
static int64_t getIntValueFromConstOp(mlir::Value val) {
2203-
auto constOp = mlir::cast<mlir::cir::ConstantOp>(val.getDefiningOp());
2204-
return (mlir::cast<mlir::cir::IntAttr>(constOp.getValue()))
2205-
.getValue()
2206-
.getSExtValue();
2229+
return builder
2230+
.create<mlir::cir::IntrinsicCallOp>(
2231+
loc, builder.getStringAttr(intrinsicName), funcResTy, args)
2232+
.getResult();
22072233
}
22082234

22092235
/// This function `buildCommonNeonCallPattern0` implements a common way
@@ -2231,23 +2257,6 @@ buildCommonNeonCallPattern0(CIRGenFunction &cgf, llvm::StringRef intrincsName,
22312257
return builder.createBitcast(res, resultType);
22322258
}
22332259

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

0 commit comments

Comments
 (0)