6
6
//
7
7
// ===----------------------------------------------------------------------===//
8
8
//
9
- // Replaces calls to LLVM vector intrinsics (i.e., calls to LLVM intrinsics
10
- // with vector operands) with matching calls to functions from a vector
11
- // library (e.g., libmvec, SVML) according to TargetLibraryInfo.
9
+ // Replaces instructions to LLVM vector intrinsics (i.e., the frem instruction
10
+ // or calls to LLVM intrinsics with vector operands) with matching calls to
11
+ // functions from a vector library (e.g., libmvec, SVML) according to
12
+ // TargetLibraryInfo.
12
13
//
13
14
// ===----------------------------------------------------------------------===//
14
15
@@ -69,9 +70,8 @@ Function *getTLIFunction(Module *M, FunctionType *VectorFTy,
69
70
return TLIFunc;
70
71
}
71
72
72
- // / Replace the Instruction \p I, that may be a vector intrinsic CallInst or
73
- // / the frem instruction, with a call to the corresponding function from the
74
- // / vector library ( \p TLIVecFunc ).
73
+ // / Replace the Instruction \p I with a call to the corresponding function from
74
+ // / the vector library ( \p TLIVecFunc ).
75
75
static void replaceWithTLIFunction (Instruction &I, VFInfo &Info,
76
76
Function *TLIVecFunc) {
77
77
IRBuilder<> IRBuilder (&I);
@@ -98,51 +98,53 @@ static void replaceWithTLIFunction(Instruction &I, VFInfo &Info,
98
98
99
99
// / Returns true when successfully replaced \p I with a suitable function taking
100
100
// / vector arguments, based on available mappings in the \p TLI. Currently only
101
- // / works when \p I is a call to vectorized intrinsic or the FRem Instruction.
101
+ // / works when \p I is a call to vectorized intrinsic or the frem Instruction.
102
102
static bool replaceWithCallToVeclib (const TargetLibraryInfo &TLI,
103
103
Instruction &I) {
104
- CallInst *CI = dyn_cast<CallInst>(&I);
105
- Intrinsic::ID IID = Intrinsic::not_intrinsic;
106
- if (CI)
107
- IID = CI->getCalledFunction ()->getIntrinsicID ();
108
- // Compute arguments types of the corresponding scalar call. Additionally
109
- // checks if in the vector call, all vector operands have the same EC.
104
+ std::string ScalarName;
110
105
ElementCount VF = ElementCount::getFixed (0 );
106
+ CallInst *CI = dyn_cast<CallInst>(&I);
111
107
SmallVector<Type *, 8 > ScalarArgTypes;
112
- for (auto Arg : enumerate(CI ? CI->args () : I.operands ())) {
113
- auto *ArgTy = Arg.value ()->getType ();
114
- if (CI && isVectorIntrinsicWithScalarOpAtArg (IID, Arg.index ())) {
115
- ScalarArgTypes.push_back (ArgTy);
116
- } else {
117
- auto *VectorArgTy = dyn_cast<VectorType>(ArgTy);
118
- // We are expecting only VectorTypes, as:
119
- // - with a CallInst, scalar operands are handled earlier
120
- // - with the FRem Instruction, both operands must be vectors.
121
- if (!VectorArgTy)
122
- return false ;
123
- ScalarArgTypes.push_back (ArgTy->getScalarType ());
124
- // Disallow vector arguments with different VFs. When processing the first
125
- // vector argument, store it's VF, and for the rest ensure that they match
126
- // it.
127
- if (VF.isZero ())
128
- VF = VectorArgTy->getElementCount ();
129
- else if (VF != VectorArgTy->getElementCount ())
130
- return false ;
131
- }
132
- }
133
-
134
- // Try to reconstruct the name for the scalar version of the instruction.
135
- std::string ScalarName;
136
108
if (CI) {
137
- // For intrinsics, use scalar argument types
109
+ Intrinsic::ID IID = Intrinsic::not_intrinsic;
110
+ IID = CI->getCalledFunction ()->getIntrinsicID ();
111
+ // Compute arguments types of the corresponding scalar call. Additionally
112
+ // checks if in the vector call, all vector operands have the same EC.
113
+ for (auto Arg : enumerate(CI ? CI->args () : I.operands ())) {
114
+ auto *ArgTy = Arg.value ()->getType ();
115
+ if (CI && isVectorIntrinsicWithScalarOpAtArg (IID, Arg.index ())) {
116
+ ScalarArgTypes.push_back (ArgTy);
117
+ } else {
118
+ auto *VectorArgTy = dyn_cast<VectorType>(ArgTy);
119
+ // We are expecting only VectorTypes, as:
120
+ // - with a CallInst, scalar operands are handled earlier
121
+ // - with the frem Instruction, both operands must be vectors.
122
+ if (!VectorArgTy)
123
+ return false ;
124
+ ScalarArgTypes.push_back (ArgTy->getScalarType ());
125
+ // Disallow vector arguments with different VFs. When processing the
126
+ // first vector argument, store it's VF, and for the rest ensure that
127
+ // they match it.
128
+ if (VF.isZero ())
129
+ VF = VectorArgTy->getElementCount ();
130
+ else if (VF != VectorArgTy->getElementCount ())
131
+ return false ;
132
+ }
133
+ }
134
+ // Try to reconstruct the name for the scalar version of the instruction,
135
+ // using scalar argument types.
138
136
ScalarName = Intrinsic::isOverloaded (IID)
139
137
? Intrinsic::getName (IID, ScalarArgTypes, I.getModule ())
140
138
: Intrinsic::getName (IID).str ();
141
139
} else {
142
140
LibFunc Func;
143
- if (!TLI.getLibFunc (I.getOpcode (), I.getType ()->getScalarType (), Func))
141
+ auto *ScalarTy = I.getType ()->getScalarType ();
142
+ if (!TLI.getLibFunc (I.getOpcode (), ScalarTy, Func))
144
143
return false ;
145
144
ScalarName = TLI.getName (Func);
145
+ ScalarArgTypes = {ScalarTy, ScalarTy};
146
+ if (auto *VTy = dyn_cast<VectorType>(I.getType ()))
147
+ VF = VTy->getElementCount ();
146
148
}
147
149
148
150
// Try to find the mapping for the scalar version of this intrinsic and the
@@ -181,12 +183,11 @@ static bool replaceWithCallToVeclib(const TargetLibraryInfo &TLI,
181
183
return true ;
182
184
}
183
185
184
- // / Supported Instructions \p I are either FRem or CallInsts to Intrinsics.
186
+ // / Supported Instructions \p I are either frem or CallInsts to Intrinsics.
185
187
static bool isSupportedInstruction (Instruction *I) {
186
188
if (auto *CI = dyn_cast<CallInst>(I)) {
187
- if (!CI->getCalledFunction ())
188
- return false ;
189
- if (CI->getCalledFunction ()->getIntrinsicID () == Intrinsic::not_intrinsic)
189
+ if (!CI->getCalledFunction () ||
190
+ CI->getCalledFunction ()->getIntrinsicID () == Intrinsic::not_intrinsic)
190
191
return false ;
191
192
} else if (I->getOpcode () != Instruction::FRem)
192
193
return false ;
0 commit comments