@@ -1272,9 +1272,6 @@ static bool upgradeIntrinsicFunction1(Function *F, Function *&NewFn,
1272
1272
// nvvm.bitcast.{f2i,i2f,ll2d,d2ll}
1273
1273
Expand =
1274
1274
Name == " f2i" || Name == " i2f" || Name == " ll2d" || Name == " d2ll" ;
1275
- else if (Name.consume_front (" rotate." ))
1276
- // nvvm.rotate.{b32,b64,right.b64}
1277
- Expand = Name == " b32" || Name == " b64" || Name == " right.b64" ;
1278
1275
else
1279
1276
Expand = false ;
1280
1277
@@ -2261,108 +2258,6 @@ void llvm::UpgradeInlineAsmString(std::string *AsmStr) {
2261
2258
}
2262
2259
}
2263
2260
2264
- static Value *upgradeNVVMIntrinsicCall (StringRef Name, CallBase *CI,
2265
- Function *F, IRBuilder<> &Builder) {
2266
- Value *Rep = nullptr ;
2267
-
2268
- if (Name == " abs.i" || Name == " abs.ll" ) {
2269
- Value *Arg = CI->getArgOperand (0 );
2270
- Value *Neg = Builder.CreateNeg (Arg, " neg" );
2271
- Value *Cmp = Builder.CreateICmpSGE (
2272
- Arg, llvm::Constant::getNullValue (Arg->getType ()), " abs.cond" );
2273
- Rep = Builder.CreateSelect (Cmp, Arg, Neg, " abs" );
2274
- } else if (Name.starts_with (" atomic.load.add.f32.p" ) ||
2275
- Name.starts_with (" atomic.load.add.f64.p" )) {
2276
- Value *Ptr = CI->getArgOperand (0 );
2277
- Value *Val = CI->getArgOperand (1 );
2278
- Rep = Builder.CreateAtomicRMW (AtomicRMWInst::FAdd, Ptr, Val, MaybeAlign (),
2279
- AtomicOrdering::SequentiallyConsistent);
2280
- } else if (Name.consume_front (" max." ) &&
2281
- (Name == " s" || Name == " i" || Name == " ll" || Name == " us" ||
2282
- Name == " ui" || Name == " ull" )) {
2283
- Value *Arg0 = CI->getArgOperand (0 );
2284
- Value *Arg1 = CI->getArgOperand (1 );
2285
- Value *Cmp = Name.starts_with (" u" )
2286
- ? Builder.CreateICmpUGE (Arg0, Arg1, " max.cond" )
2287
- : Builder.CreateICmpSGE (Arg0, Arg1, " max.cond" );
2288
- Rep = Builder.CreateSelect (Cmp, Arg0, Arg1, " max" );
2289
- } else if (Name.consume_front (" min." ) &&
2290
- (Name == " s" || Name == " i" || Name == " ll" || Name == " us" ||
2291
- Name == " ui" || Name == " ull" )) {
2292
- Value *Arg0 = CI->getArgOperand (0 );
2293
- Value *Arg1 = CI->getArgOperand (1 );
2294
- Value *Cmp = Name.starts_with (" u" )
2295
- ? Builder.CreateICmpULE (Arg0, Arg1, " min.cond" )
2296
- : Builder.CreateICmpSLE (Arg0, Arg1, " min.cond" );
2297
- Rep = Builder.CreateSelect (Cmp, Arg0, Arg1, " min" );
2298
- } else if (Name == " clz.ll" ) {
2299
- // llvm.nvvm.clz.ll returns an i32, but llvm.ctlz.i64 returns an i64.
2300
- Value *Arg = CI->getArgOperand (0 );
2301
- Value *Ctlz = Builder.CreateCall (
2302
- Intrinsic::getDeclaration (F->getParent (), Intrinsic::ctlz,
2303
- {Arg->getType ()}),
2304
- {Arg, Builder.getFalse ()}, " ctlz" );
2305
- Rep = Builder.CreateTrunc (Ctlz, Builder.getInt32Ty (), " ctlz.trunc" );
2306
- } else if (Name == " popc.ll" ) {
2307
- // llvm.nvvm.popc.ll returns an i32, but llvm.ctpop.i64 returns an
2308
- // i64.
2309
- Value *Arg = CI->getArgOperand (0 );
2310
- Value *Popc = Builder.CreateCall (
2311
- Intrinsic::getDeclaration (F->getParent (), Intrinsic::ctpop,
2312
- {Arg->getType ()}),
2313
- Arg, " ctpop" );
2314
- Rep = Builder.CreateTrunc (Popc, Builder.getInt32Ty (), " ctpop.trunc" );
2315
- } else if (Name == " h2f" ) {
2316
- Rep = Builder.CreateCall (
2317
- Intrinsic::getDeclaration (F->getParent (), Intrinsic::convert_from_fp16,
2318
- {Builder.getFloatTy ()}),
2319
- CI->getArgOperand (0 ), " h2f" );
2320
- } else if (Name.consume_front (" bitcast." ) &&
2321
- (Name == " f2i" || Name == " i2f" || Name == " ll2d" ||
2322
- Name == " d2ll" )) {
2323
- Rep = Builder.CreateBitCast (CI->getArgOperand (0 ), CI->getType ());
2324
- } else if (Name == " rotate.b32" ) {
2325
- Value *Arg = CI->getOperand (0 );
2326
- Value *ShiftAmt = CI->getOperand (1 );
2327
- Rep = Builder.CreateIntrinsic (Builder.getInt32Ty (), Intrinsic::fshl,
2328
- {Arg, Arg, ShiftAmt});
2329
- } else if (Name == " rotate.b64" ) {
2330
- Type *Int64Ty = Builder.getInt64Ty ();
2331
- Value *Arg = CI->getOperand (0 );
2332
- Value *ZExtShiftAmt = Builder.CreateZExt (CI->getOperand (1 ), Int64Ty);
2333
- Rep = Builder.CreateIntrinsic (Int64Ty, Intrinsic::fshl,
2334
- {Arg, Arg, ZExtShiftAmt});
2335
- } else if (Name == " rotate.right.b64" ) {
2336
- Type *Int64Ty = Builder.getInt64Ty ();
2337
- Value *Arg = CI->getOperand (0 );
2338
- Value *ZExtShiftAmt = Builder.CreateZExt (CI->getOperand (1 ), Int64Ty);
2339
- Rep = Builder.CreateIntrinsic (Int64Ty, Intrinsic::fshr,
2340
- {Arg, Arg, ZExtShiftAmt});
2341
- } else {
2342
- Intrinsic::ID IID = shouldUpgradeNVPTXBF16Intrinsic (Name);
2343
- if (IID != Intrinsic::not_intrinsic &&
2344
- !F->getReturnType ()->getScalarType ()->isBFloatTy ()) {
2345
- rename (F);
2346
- Function *NewFn = Intrinsic::getDeclaration (F->getParent (), IID);
2347
- SmallVector<Value *, 2 > Args;
2348
- for (size_t I = 0 ; I < NewFn->arg_size (); ++I) {
2349
- Value *Arg = CI->getArgOperand (I);
2350
- Type *OldType = Arg->getType ();
2351
- Type *NewType = NewFn->getArg (I)->getType ();
2352
- Args.push_back (
2353
- (OldType->isIntegerTy () && NewType->getScalarType ()->isBFloatTy ())
2354
- ? Builder.CreateBitCast (Arg, NewType)
2355
- : Arg);
2356
- }
2357
- Rep = Builder.CreateCall (NewFn, Args);
2358
- if (F->getReturnType ()->isIntegerTy ())
2359
- Rep = Builder.CreateBitCast (Rep, F->getReturnType ());
2360
- }
2361
- }
2362
-
2363
- return Rep;
2364
- }
2365
-
2366
2261
static Value *upgradeX86IntrinsicCall (StringRef Name, CallBase *CI, Function *F,
2367
2262
IRBuilder<> &Builder) {
2368
2263
LLVMContext &C = F->getContext ();
@@ -4313,8 +4208,85 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) {
4313
4208
4314
4209
if (!IsX86 && Name == " stackprotectorcheck" ) {
4315
4210
Rep = nullptr ;
4211
+ } else if (IsNVVM && (Name == " abs.i" || Name == " abs.ll" )) {
4212
+ Value *Arg = CI->getArgOperand (0 );
4213
+ Value *Neg = Builder.CreateNeg (Arg, " neg" );
4214
+ Value *Cmp = Builder.CreateICmpSGE (
4215
+ Arg, llvm::Constant::getNullValue (Arg->getType ()), " abs.cond" );
4216
+ Rep = Builder.CreateSelect (Cmp, Arg, Neg, " abs" );
4217
+ } else if (IsNVVM && (Name.starts_with (" atomic.load.add.f32.p" ) ||
4218
+ Name.starts_with (" atomic.load.add.f64.p" ))) {
4219
+ Value *Ptr = CI->getArgOperand (0 );
4220
+ Value *Val = CI->getArgOperand (1 );
4221
+ Rep = Builder.CreateAtomicRMW (AtomicRMWInst::FAdd, Ptr, Val, MaybeAlign (),
4222
+ AtomicOrdering::SequentiallyConsistent);
4223
+ } else if (IsNVVM && Name.consume_front (" max." ) &&
4224
+ (Name == " s" || Name == " i" || Name == " ll" || Name == " us" ||
4225
+ Name == " ui" || Name == " ull" )) {
4226
+ Value *Arg0 = CI->getArgOperand (0 );
4227
+ Value *Arg1 = CI->getArgOperand (1 );
4228
+ Value *Cmp = Name.starts_with (" u" )
4229
+ ? Builder.CreateICmpUGE (Arg0, Arg1, " max.cond" )
4230
+ : Builder.CreateICmpSGE (Arg0, Arg1, " max.cond" );
4231
+ Rep = Builder.CreateSelect (Cmp, Arg0, Arg1, " max" );
4232
+ } else if (IsNVVM && Name.consume_front (" min." ) &&
4233
+ (Name == " s" || Name == " i" || Name == " ll" || Name == " us" ||
4234
+ Name == " ui" || Name == " ull" )) {
4235
+ Value *Arg0 = CI->getArgOperand (0 );
4236
+ Value *Arg1 = CI->getArgOperand (1 );
4237
+ Value *Cmp = Name.starts_with (" u" )
4238
+ ? Builder.CreateICmpULE (Arg0, Arg1, " min.cond" )
4239
+ : Builder.CreateICmpSLE (Arg0, Arg1, " min.cond" );
4240
+ Rep = Builder.CreateSelect (Cmp, Arg0, Arg1, " min" );
4241
+ } else if (IsNVVM && Name == " clz.ll" ) {
4242
+ // llvm.nvvm.clz.ll returns an i32, but llvm.ctlz.i64 returns an i64.
4243
+ Value *Arg = CI->getArgOperand (0 );
4244
+ Value *Ctlz = Builder.CreateCall (
4245
+ Intrinsic::getDeclaration (F->getParent (), Intrinsic::ctlz,
4246
+ {Arg->getType ()}),
4247
+ {Arg, Builder.getFalse ()}, " ctlz" );
4248
+ Rep = Builder.CreateTrunc (Ctlz, Builder.getInt32Ty (), " ctlz.trunc" );
4249
+ } else if (IsNVVM && Name == " popc.ll" ) {
4250
+ // llvm.nvvm.popc.ll returns an i32, but llvm.ctpop.i64 returns an
4251
+ // i64.
4252
+ Value *Arg = CI->getArgOperand (0 );
4253
+ Value *Popc = Builder.CreateCall (
4254
+ Intrinsic::getDeclaration (F->getParent (), Intrinsic::ctpop,
4255
+ {Arg->getType ()}),
4256
+ Arg, " ctpop" );
4257
+ Rep = Builder.CreateTrunc (Popc, Builder.getInt32Ty (), " ctpop.trunc" );
4316
4258
} else if (IsNVVM) {
4317
- Rep = upgradeNVVMIntrinsicCall (Name, CI, F, Builder);
4259
+ if (Name == " h2f" ) {
4260
+ Rep =
4261
+ Builder.CreateCall (Intrinsic::getDeclaration (
4262
+ F->getParent (), Intrinsic::convert_from_fp16,
4263
+ {Builder.getFloatTy ()}),
4264
+ CI->getArgOperand (0 ), " h2f" );
4265
+ } else if (Name.consume_front (" bitcast." ) &&
4266
+ (Name == " f2i" || Name == " i2f" || Name == " ll2d" ||
4267
+ Name == " d2ll" )) {
4268
+ Rep = Builder.CreateBitCast (CI->getArgOperand (0 ), CI->getType ());
4269
+ } else {
4270
+ Intrinsic::ID IID = shouldUpgradeNVPTXBF16Intrinsic (Name);
4271
+ if (IID != Intrinsic::not_intrinsic &&
4272
+ !F->getReturnType ()->getScalarType ()->isBFloatTy ()) {
4273
+ rename (F);
4274
+ NewFn = Intrinsic::getDeclaration (F->getParent (), IID);
4275
+ SmallVector<Value *, 2 > Args;
4276
+ for (size_t I = 0 ; I < NewFn->arg_size (); ++I) {
4277
+ Value *Arg = CI->getArgOperand (I);
4278
+ Type *OldType = Arg->getType ();
4279
+ Type *NewType = NewFn->getArg (I)->getType ();
4280
+ Args.push_back ((OldType->isIntegerTy () &&
4281
+ NewType->getScalarType ()->isBFloatTy ())
4282
+ ? Builder.CreateBitCast (Arg, NewType)
4283
+ : Arg);
4284
+ }
4285
+ Rep = Builder.CreateCall (NewFn, Args);
4286
+ if (F->getReturnType ()->isIntegerTy ())
4287
+ Rep = Builder.CreateBitCast (Rep, F->getReturnType ());
4288
+ }
4289
+ }
4318
4290
} else if (IsX86) {
4319
4291
Rep = upgradeX86IntrinsicCall (Name, CI, F, Builder);
4320
4292
} else if (IsARM) {
0 commit comments