xref: /freebsd/contrib/llvm-project/clang/lib/CodeGen/TargetBuiltins/PPC.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
1 //===---------- PPC.cpp - Emit LLVM Code for builtins ---------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This contains code to emit Builtin calls as LLVM code.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "CGBuiltin.h"
14 #include "clang/Basic/TargetBuiltins.h"
15 #include "llvm/IR/InlineAsm.h"
16 #include "llvm/IR/IntrinsicsPowerPC.h"
17 #include "llvm/Support/ScopedPrinter.h"
18 
19 using namespace clang;
20 using namespace CodeGen;
21 using namespace llvm;
22 
23 static llvm::Value *emitPPCLoadReserveIntrinsic(CodeGenFunction &CGF,
24                                                 unsigned BuiltinID,
25                                                 const CallExpr *E) {
26   Value *Addr = CGF.EmitScalarExpr(E->getArg(0));
27 
28   SmallString<64> Asm;
29   raw_svector_ostream AsmOS(Asm);
30   llvm::IntegerType *RetType = CGF.Int32Ty;
31 
32   switch (BuiltinID) {
33   case clang::PPC::BI__builtin_ppc_ldarx:
34     AsmOS << "ldarx ";
35     RetType = CGF.Int64Ty;
36     break;
37   case clang::PPC::BI__builtin_ppc_lwarx:
38     AsmOS << "lwarx ";
39     RetType = CGF.Int32Ty;
40     break;
41   case clang::PPC::BI__builtin_ppc_lharx:
42     AsmOS << "lharx ";
43     RetType = CGF.Int16Ty;
44     break;
45   case clang::PPC::BI__builtin_ppc_lbarx:
46     AsmOS << "lbarx ";
47     RetType = CGF.Int8Ty;
48     break;
49   default:
50     llvm_unreachable("Expected only PowerPC load reserve intrinsics");
51   }
52 
53   AsmOS << "$0, ${1:y}";
54 
55   std::string Constraints = "=r,*Z,~{memory}";
56   std::string_view MachineClobbers = CGF.getTarget().getClobbers();
57   if (!MachineClobbers.empty()) {
58     Constraints += ',';
59     Constraints += MachineClobbers;
60   }
61 
62   llvm::Type *PtrType = CGF.UnqualPtrTy;
63   llvm::FunctionType *FTy = llvm::FunctionType::get(RetType, {PtrType}, false);
64 
65   llvm::InlineAsm *IA =
66       llvm::InlineAsm::get(FTy, Asm, Constraints, /*hasSideEffects=*/true);
67   llvm::CallInst *CI = CGF.Builder.CreateCall(IA, {Addr});
68   CI->addParamAttr(
69       0, Attribute::get(CGF.getLLVMContext(), Attribute::ElementType, RetType));
70   return CI;
71 }
72 
73 Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
74                                            const CallExpr *E) {
75   // Do not emit the builtin arguments in the arguments of a function call,
76   // because the evaluation order of function arguments is not specified in C++.
77   // This is important when testing to ensure the arguments are emitted in the
78   // same order every time. Eg:
79   // Instead of:
80   //   return Builder.CreateFDiv(EmitScalarExpr(E->getArg(0)),
81   //                             EmitScalarExpr(E->getArg(1)), "swdiv");
82   // Use:
83   //   Value *Op0 = EmitScalarExpr(E->getArg(0));
84   //   Value *Op1 = EmitScalarExpr(E->getArg(1));
85   //   return Builder.CreateFDiv(Op0, Op1, "swdiv")
86 
87   Intrinsic::ID ID = Intrinsic::not_intrinsic;
88 
89 #include "llvm/TargetParser/PPCTargetParser.def"
90   auto GenAIXPPCBuiltinCpuExpr = [&](unsigned SupportMethod, unsigned FieldIdx,
91                                      unsigned Mask, CmpInst::Predicate CompOp,
92                                      unsigned OpValue) -> Value * {
93     if (SupportMethod == BUILTIN_PPC_FALSE)
94       return llvm::ConstantInt::getFalse(ConvertType(E->getType()));
95 
96     if (SupportMethod == BUILTIN_PPC_TRUE)
97       return llvm::ConstantInt::getTrue(ConvertType(E->getType()));
98 
99     assert(SupportMethod <= SYS_CALL && "Invalid value for SupportMethod.");
100 
101     llvm::Value *FieldValue = nullptr;
102     if (SupportMethod == USE_SYS_CONF) {
103       llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE);
104       llvm::Constant *SysConf =
105           CGM.CreateRuntimeVariable(STy, "_system_configuration");
106 
107       // Grab the appropriate field from _system_configuration.
108       llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0),
109                              ConstantInt::get(Int32Ty, FieldIdx)};
110 
111       FieldValue = Builder.CreateInBoundsGEP(STy, SysConf, Idxs);
112       FieldValue = Builder.CreateAlignedLoad(Int32Ty, FieldValue,
113                                              CharUnits::fromQuantity(4));
114     } else if (SupportMethod == SYS_CALL) {
115       llvm::FunctionType *FTy =
116           llvm::FunctionType::get(Int64Ty, Int32Ty, false);
117       llvm::FunctionCallee Func =
118           CGM.CreateRuntimeFunction(FTy, "getsystemcfg");
119 
120       FieldValue =
121           Builder.CreateCall(Func, {ConstantInt::get(Int32Ty, FieldIdx)});
122     }
123     assert(FieldValue &&
124            "SupportMethod value is not defined in PPCTargetParser.def.");
125 
126     if (Mask)
127       FieldValue = Builder.CreateAnd(FieldValue, Mask);
128 
129     llvm::Type *ValueType = FieldValue->getType();
130     bool IsValueType64Bit = ValueType->isIntegerTy(64);
131     assert(
132         (IsValueType64Bit || ValueType->isIntegerTy(32)) &&
133         "Only 32/64-bit integers are supported in GenAIXPPCBuiltinCpuExpr().");
134 
135     return Builder.CreateICmp(
136         CompOp, FieldValue,
137         ConstantInt::get(IsValueType64Bit ? Int64Ty : Int32Ty, OpValue));
138   };
139 
140   switch (BuiltinID) {
141   default: return nullptr;
142 
143   case Builtin::BI__builtin_cpu_is: {
144     const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts();
145     StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString();
146     llvm::Triple Triple = getTarget().getTriple();
147 
148     typedef std::tuple<unsigned, unsigned, unsigned, unsigned> CPUInfo;
149 
150     auto [LinuxSupportMethod, LinuxIDValue, AIXSupportMethod, AIXIDValue] =
151         static_cast<CPUInfo>(StringSwitch<CPUInfo>(CPUStr)
152 #define PPC_CPU(NAME, Linux_SUPPORT_METHOD, LinuxID, AIX_SUPPORT_METHOD,       \
153                 AIXID)                                                         \
154   .Case(NAME, {Linux_SUPPORT_METHOD, LinuxID, AIX_SUPPORT_METHOD, AIXID})
155 #include "llvm/TargetParser/PPCTargetParser.def"
156                                  .Default({BUILTIN_PPC_UNSUPPORTED, 0,
157                                            BUILTIN_PPC_UNSUPPORTED, 0}));
158 
159     if (Triple.isOSAIX()) {
160       assert((AIXSupportMethod != BUILTIN_PPC_UNSUPPORTED) &&
161              "Invalid CPU name. Missed by SemaChecking?");
162       return GenAIXPPCBuiltinCpuExpr(AIXSupportMethod, AIX_SYSCON_IMPL_IDX, 0,
163                                      ICmpInst::ICMP_EQ, AIXIDValue);
164     }
165 
166     assert(Triple.isOSLinux() &&
167            "__builtin_cpu_is() is only supported for AIX and Linux.");
168 
169     assert((LinuxSupportMethod != BUILTIN_PPC_UNSUPPORTED) &&
170            "Invalid CPU name. Missed by SemaChecking?");
171 
172     if (LinuxSupportMethod == BUILTIN_PPC_FALSE)
173       return llvm::ConstantInt::getFalse(ConvertType(E->getType()));
174 
175     Value *Op0 = llvm::ConstantInt::get(Int32Ty, PPC_FAWORD_CPUID);
176     llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_fixed_addr_ld);
177     Value *TheCall = Builder.CreateCall(F, {Op0}, "cpu_is");
178     return Builder.CreateICmpEQ(TheCall,
179                                 llvm::ConstantInt::get(Int32Ty, LinuxIDValue));
180   }
181   case Builtin::BI__builtin_cpu_supports: {
182     llvm::Triple Triple = getTarget().getTriple();
183     const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts();
184     StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString();
185     if (Triple.isOSAIX()) {
186       typedef std::tuple<unsigned, unsigned, unsigned, CmpInst::Predicate,
187                          unsigned>
188           CPUSupportType;
189       auto [SupportMethod, FieldIdx, Mask, CompOp, Value] =
190           static_cast<CPUSupportType>(StringSwitch<CPUSupportType>(CPUStr)
191 #define PPC_AIX_FEATURE(NAME, DESC, SUPPORT_METHOD, INDEX, MASK, COMP_OP,      \
192                         VALUE)                                                 \
193   .Case(NAME, {SUPPORT_METHOD, INDEX, MASK, COMP_OP, VALUE})
194 #include "llvm/TargetParser/PPCTargetParser.def"
195                                           .Default({BUILTIN_PPC_FALSE, 0, 0,
196                                                     CmpInst::Predicate(), 0}));
197       return GenAIXPPCBuiltinCpuExpr(SupportMethod, FieldIdx, Mask, CompOp,
198                                      Value);
199     }
200 
201     assert(Triple.isOSLinux() &&
202            "__builtin_cpu_supports() is only supported for AIX and Linux.");
203     auto [FeatureWord, BitMask] =
204         StringSwitch<std::pair<unsigned, unsigned>>(CPUStr)
205 #define PPC_LNX_FEATURE(Name, Description, EnumName, Bitmask, FA_WORD)         \
206   .Case(Name, {FA_WORD, Bitmask})
207 #include "llvm/TargetParser/PPCTargetParser.def"
208             .Default({0, 0});
209     if (!BitMask)
210       return Builder.getFalse();
211     Value *Op0 = llvm::ConstantInt::get(Int32Ty, FeatureWord);
212     llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_fixed_addr_ld);
213     Value *TheCall = Builder.CreateCall(F, {Op0}, "cpu_supports");
214     Value *Mask =
215         Builder.CreateAnd(TheCall, llvm::ConstantInt::get(Int32Ty, BitMask));
216     return Builder.CreateICmpNE(Mask, llvm::Constant::getNullValue(Int32Ty));
217 #undef PPC_FAWORD_HWCAP
218 #undef PPC_FAWORD_HWCAP2
219 #undef PPC_FAWORD_CPUID
220   }
221 
222   // __builtin_ppc_get_timebase is GCC 4.8+'s PowerPC-specific name for what we
223   // call __builtin_readcyclecounter.
224   case PPC::BI__builtin_ppc_get_timebase:
225     return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::readcyclecounter));
226 
227   // vec_ld, vec_xl_be, vec_lvsl, vec_lvsr
228   case PPC::BI__builtin_altivec_lvx:
229   case PPC::BI__builtin_altivec_lvxl:
230   case PPC::BI__builtin_altivec_lvebx:
231   case PPC::BI__builtin_altivec_lvehx:
232   case PPC::BI__builtin_altivec_lvewx:
233   case PPC::BI__builtin_altivec_lvsl:
234   case PPC::BI__builtin_altivec_lvsr:
235   case PPC::BI__builtin_vsx_lxvd2x:
236   case PPC::BI__builtin_vsx_lxvw4x:
237   case PPC::BI__builtin_vsx_lxvd2x_be:
238   case PPC::BI__builtin_vsx_lxvw4x_be:
239   case PPC::BI__builtin_vsx_lxvl:
240   case PPC::BI__builtin_vsx_lxvll:
241   {
242     SmallVector<Value *, 2> Ops;
243     Ops.push_back(EmitScalarExpr(E->getArg(0)));
244     Ops.push_back(EmitScalarExpr(E->getArg(1)));
245     if (!(BuiltinID == PPC::BI__builtin_vsx_lxvl ||
246           BuiltinID == PPC::BI__builtin_vsx_lxvll)) {
247       Ops[0] = Builder.CreateGEP(Int8Ty, Ops[1], Ops[0]);
248       Ops.pop_back();
249     }
250 
251     switch (BuiltinID) {
252     default: llvm_unreachable("Unsupported ld/lvsl/lvsr intrinsic!");
253     case PPC::BI__builtin_altivec_lvx:
254       ID = Intrinsic::ppc_altivec_lvx;
255       break;
256     case PPC::BI__builtin_altivec_lvxl:
257       ID = Intrinsic::ppc_altivec_lvxl;
258       break;
259     case PPC::BI__builtin_altivec_lvebx:
260       ID = Intrinsic::ppc_altivec_lvebx;
261       break;
262     case PPC::BI__builtin_altivec_lvehx:
263       ID = Intrinsic::ppc_altivec_lvehx;
264       break;
265     case PPC::BI__builtin_altivec_lvewx:
266       ID = Intrinsic::ppc_altivec_lvewx;
267       break;
268     case PPC::BI__builtin_altivec_lvsl:
269       ID = Intrinsic::ppc_altivec_lvsl;
270       break;
271     case PPC::BI__builtin_altivec_lvsr:
272       ID = Intrinsic::ppc_altivec_lvsr;
273       break;
274     case PPC::BI__builtin_vsx_lxvd2x:
275       ID = Intrinsic::ppc_vsx_lxvd2x;
276       break;
277     case PPC::BI__builtin_vsx_lxvw4x:
278       ID = Intrinsic::ppc_vsx_lxvw4x;
279       break;
280     case PPC::BI__builtin_vsx_lxvd2x_be:
281       ID = Intrinsic::ppc_vsx_lxvd2x_be;
282       break;
283     case PPC::BI__builtin_vsx_lxvw4x_be:
284       ID = Intrinsic::ppc_vsx_lxvw4x_be;
285       break;
286     case PPC::BI__builtin_vsx_lxvl:
287       ID = Intrinsic::ppc_vsx_lxvl;
288       break;
289     case PPC::BI__builtin_vsx_lxvll:
290       ID = Intrinsic::ppc_vsx_lxvll;
291       break;
292     }
293     llvm::Function *F = CGM.getIntrinsic(ID);
294     return Builder.CreateCall(F, Ops, "");
295   }
296 
297   // vec_st, vec_xst_be
298   case PPC::BI__builtin_altivec_stvx:
299   case PPC::BI__builtin_altivec_stvxl:
300   case PPC::BI__builtin_altivec_stvebx:
301   case PPC::BI__builtin_altivec_stvehx:
302   case PPC::BI__builtin_altivec_stvewx:
303   case PPC::BI__builtin_vsx_stxvd2x:
304   case PPC::BI__builtin_vsx_stxvw4x:
305   case PPC::BI__builtin_vsx_stxvd2x_be:
306   case PPC::BI__builtin_vsx_stxvw4x_be:
307   case PPC::BI__builtin_vsx_stxvl:
308   case PPC::BI__builtin_vsx_stxvll:
309   {
310     SmallVector<Value *, 3> Ops;
311     Ops.push_back(EmitScalarExpr(E->getArg(0)));
312     Ops.push_back(EmitScalarExpr(E->getArg(1)));
313     Ops.push_back(EmitScalarExpr(E->getArg(2)));
314     if (!(BuiltinID == PPC::BI__builtin_vsx_stxvl ||
315           BuiltinID == PPC::BI__builtin_vsx_stxvll)) {
316       Ops[1] = Builder.CreateGEP(Int8Ty, Ops[2], Ops[1]);
317       Ops.pop_back();
318     }
319 
320     switch (BuiltinID) {
321     default: llvm_unreachable("Unsupported st intrinsic!");
322     case PPC::BI__builtin_altivec_stvx:
323       ID = Intrinsic::ppc_altivec_stvx;
324       break;
325     case PPC::BI__builtin_altivec_stvxl:
326       ID = Intrinsic::ppc_altivec_stvxl;
327       break;
328     case PPC::BI__builtin_altivec_stvebx:
329       ID = Intrinsic::ppc_altivec_stvebx;
330       break;
331     case PPC::BI__builtin_altivec_stvehx:
332       ID = Intrinsic::ppc_altivec_stvehx;
333       break;
334     case PPC::BI__builtin_altivec_stvewx:
335       ID = Intrinsic::ppc_altivec_stvewx;
336       break;
337     case PPC::BI__builtin_vsx_stxvd2x:
338       ID = Intrinsic::ppc_vsx_stxvd2x;
339       break;
340     case PPC::BI__builtin_vsx_stxvw4x:
341       ID = Intrinsic::ppc_vsx_stxvw4x;
342       break;
343     case PPC::BI__builtin_vsx_stxvd2x_be:
344       ID = Intrinsic::ppc_vsx_stxvd2x_be;
345       break;
346     case PPC::BI__builtin_vsx_stxvw4x_be:
347       ID = Intrinsic::ppc_vsx_stxvw4x_be;
348       break;
349     case PPC::BI__builtin_vsx_stxvl:
350       ID = Intrinsic::ppc_vsx_stxvl;
351       break;
352     case PPC::BI__builtin_vsx_stxvll:
353       ID = Intrinsic::ppc_vsx_stxvll;
354       break;
355     }
356     llvm::Function *F = CGM.getIntrinsic(ID);
357     return Builder.CreateCall(F, Ops, "");
358   }
359   case PPC::BI__builtin_vsx_ldrmb: {
360     // Essentially boils down to performing an unaligned VMX load sequence so
361     // as to avoid crossing a page boundary and then shuffling the elements
362     // into the right side of the vector register.
363     Value *Op0 = EmitScalarExpr(E->getArg(0));
364     Value *Op1 = EmitScalarExpr(E->getArg(1));
365     int64_t NumBytes = cast<ConstantInt>(Op1)->getZExtValue();
366     llvm::Type *ResTy = ConvertType(E->getType());
367     bool IsLE = getTarget().isLittleEndian();
368 
369     // If the user wants the entire vector, just load the entire vector.
370     if (NumBytes == 16) {
371       Value *LD =
372           Builder.CreateLoad(Address(Op0, ResTy, CharUnits::fromQuantity(1)));
373       if (!IsLE)
374         return LD;
375 
376       // Reverse the bytes on LE.
377       SmallVector<int, 16> RevMask;
378       for (int Idx = 0; Idx < 16; Idx++)
379         RevMask.push_back(15 - Idx);
380       return Builder.CreateShuffleVector(LD, LD, RevMask);
381     }
382 
383     llvm::Function *Lvx = CGM.getIntrinsic(Intrinsic::ppc_altivec_lvx);
384     llvm::Function *Lvs = CGM.getIntrinsic(IsLE ? Intrinsic::ppc_altivec_lvsr
385                                                 : Intrinsic::ppc_altivec_lvsl);
386     llvm::Function *Vperm = CGM.getIntrinsic(Intrinsic::ppc_altivec_vperm);
387     Value *HiMem = Builder.CreateGEP(
388         Int8Ty, Op0, ConstantInt::get(Op1->getType(), NumBytes - 1));
389     Value *LoLd = Builder.CreateCall(Lvx, Op0, "ld.lo");
390     Value *HiLd = Builder.CreateCall(Lvx, HiMem, "ld.hi");
391     Value *Mask1 = Builder.CreateCall(Lvs, Op0, "mask1");
392 
393     Op0 = IsLE ? HiLd : LoLd;
394     Op1 = IsLE ? LoLd : HiLd;
395     Value *AllElts = Builder.CreateCall(Vperm, {Op0, Op1, Mask1}, "shuffle1");
396     Constant *Zero = llvm::Constant::getNullValue(IsLE ? ResTy : AllElts->getType());
397 
398     if (IsLE) {
399       SmallVector<int, 16> Consts;
400       for (int Idx = 0; Idx < 16; Idx++) {
401         int Val = (NumBytes - Idx - 1 >= 0) ? (NumBytes - Idx - 1)
402                                             : 16 - (NumBytes - Idx);
403         Consts.push_back(Val);
404       }
405       return Builder.CreateShuffleVector(Builder.CreateBitCast(AllElts, ResTy),
406                                          Zero, Consts);
407     }
408     SmallVector<Constant *, 16> Consts;
409     for (int Idx = 0; Idx < 16; Idx++)
410       Consts.push_back(Builder.getInt8(NumBytes + Idx));
411     Value *Mask2 = ConstantVector::get(Consts);
412     return Builder.CreateBitCast(
413         Builder.CreateCall(Vperm, {Zero, AllElts, Mask2}, "shuffle2"), ResTy);
414   }
415   case PPC::BI__builtin_vsx_strmb: {
416     Value *Op0 = EmitScalarExpr(E->getArg(0));
417     Value *Op1 = EmitScalarExpr(E->getArg(1));
418     Value *Op2 = EmitScalarExpr(E->getArg(2));
419     int64_t NumBytes = cast<ConstantInt>(Op1)->getZExtValue();
420     bool IsLE = getTarget().isLittleEndian();
421     auto StoreSubVec = [&](unsigned Width, unsigned Offset, unsigned EltNo) {
422       // Storing the whole vector, simply store it on BE and reverse bytes and
423       // store on LE.
424       if (Width == 16) {
425         Value *StVec = Op2;
426         if (IsLE) {
427           SmallVector<int, 16> RevMask;
428           for (int Idx = 0; Idx < 16; Idx++)
429             RevMask.push_back(15 - Idx);
430           StVec = Builder.CreateShuffleVector(Op2, Op2, RevMask);
431         }
432         return Builder.CreateStore(
433             StVec, Address(Op0, Op2->getType(), CharUnits::fromQuantity(1)));
434       }
435       auto *ConvTy = Int64Ty;
436       unsigned NumElts = 0;
437       switch (Width) {
438       default:
439         llvm_unreachable("width for stores must be a power of 2");
440       case 8:
441         ConvTy = Int64Ty;
442         NumElts = 2;
443         break;
444       case 4:
445         ConvTy = Int32Ty;
446         NumElts = 4;
447         break;
448       case 2:
449         ConvTy = Int16Ty;
450         NumElts = 8;
451         break;
452       case 1:
453         ConvTy = Int8Ty;
454         NumElts = 16;
455         break;
456       }
457       Value *Vec = Builder.CreateBitCast(
458           Op2, llvm::FixedVectorType::get(ConvTy, NumElts));
459       Value *Ptr =
460           Builder.CreateGEP(Int8Ty, Op0, ConstantInt::get(Int64Ty, Offset));
461       Value *Elt = Builder.CreateExtractElement(Vec, EltNo);
462       if (IsLE && Width > 1) {
463         Function *F = CGM.getIntrinsic(Intrinsic::bswap, ConvTy);
464         Elt = Builder.CreateCall(F, Elt);
465       }
466       return Builder.CreateStore(
467           Elt, Address(Ptr, ConvTy, CharUnits::fromQuantity(1)));
468     };
469     unsigned Stored = 0;
470     unsigned RemainingBytes = NumBytes;
471     Value *Result;
472     if (NumBytes == 16)
473       return StoreSubVec(16, 0, 0);
474     if (NumBytes >= 8) {
475       Result = StoreSubVec(8, NumBytes - 8, IsLE ? 0 : 1);
476       RemainingBytes -= 8;
477       Stored += 8;
478     }
479     if (RemainingBytes >= 4) {
480       Result = StoreSubVec(4, NumBytes - Stored - 4,
481                            IsLE ? (Stored >> 2) : 3 - (Stored >> 2));
482       RemainingBytes -= 4;
483       Stored += 4;
484     }
485     if (RemainingBytes >= 2) {
486       Result = StoreSubVec(2, NumBytes - Stored - 2,
487                            IsLE ? (Stored >> 1) : 7 - (Stored >> 1));
488       RemainingBytes -= 2;
489       Stored += 2;
490     }
491     if (RemainingBytes)
492       Result =
493           StoreSubVec(1, NumBytes - Stored - 1, IsLE ? Stored : 15 - Stored);
494     return Result;
495   }
496   // Square root
497   case PPC::BI__builtin_vsx_xvsqrtsp:
498   case PPC::BI__builtin_vsx_xvsqrtdp: {
499     llvm::Type *ResultType = ConvertType(E->getType());
500     Value *X = EmitScalarExpr(E->getArg(0));
501     if (Builder.getIsFPConstrained()) {
502       llvm::Function *F = CGM.getIntrinsic(
503           Intrinsic::experimental_constrained_sqrt, ResultType);
504       return Builder.CreateConstrainedFPCall(F, X);
505     } else {
506       llvm::Function *F = CGM.getIntrinsic(Intrinsic::sqrt, ResultType);
507       return Builder.CreateCall(F, X);
508     }
509   }
510   // Count leading zeros
511   case PPC::BI__builtin_altivec_vclzb:
512   case PPC::BI__builtin_altivec_vclzh:
513   case PPC::BI__builtin_altivec_vclzw:
514   case PPC::BI__builtin_altivec_vclzd: {
515     llvm::Type *ResultType = ConvertType(E->getType());
516     Value *X = EmitScalarExpr(E->getArg(0));
517     Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
518     Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType);
519     return Builder.CreateCall(F, {X, Undef});
520   }
521   case PPC::BI__builtin_altivec_vctzb:
522   case PPC::BI__builtin_altivec_vctzh:
523   case PPC::BI__builtin_altivec_vctzw:
524   case PPC::BI__builtin_altivec_vctzd: {
525     llvm::Type *ResultType = ConvertType(E->getType());
526     Value *X = EmitScalarExpr(E->getArg(0));
527     Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
528     Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType);
529     return Builder.CreateCall(F, {X, Undef});
530   }
531   case PPC::BI__builtin_altivec_vinsd:
532   case PPC::BI__builtin_altivec_vinsw:
533   case PPC::BI__builtin_altivec_vinsd_elt:
534   case PPC::BI__builtin_altivec_vinsw_elt: {
535     llvm::Type *ResultType = ConvertType(E->getType());
536     Value *Op0 = EmitScalarExpr(E->getArg(0));
537     Value *Op1 = EmitScalarExpr(E->getArg(1));
538     Value *Op2 = EmitScalarExpr(E->getArg(2));
539 
540     bool IsUnaligned = (BuiltinID == PPC::BI__builtin_altivec_vinsw ||
541                         BuiltinID == PPC::BI__builtin_altivec_vinsd);
542 
543     bool Is32bit = (BuiltinID == PPC::BI__builtin_altivec_vinsw ||
544                     BuiltinID == PPC::BI__builtin_altivec_vinsw_elt);
545 
546     // The third argument must be a compile time constant.
547     ConstantInt *ArgCI = dyn_cast<ConstantInt>(Op2);
548     assert(ArgCI &&
549            "Third Arg to vinsw/vinsd intrinsic must be a constant integer!");
550 
551     // Valid value for the third argument is dependent on the input type and
552     // builtin called.
553     int ValidMaxValue = 0;
554     if (IsUnaligned)
555       ValidMaxValue = (Is32bit) ? 12 : 8;
556     else
557       ValidMaxValue = (Is32bit) ? 3 : 1;
558 
559     // Get value of third argument.
560     int64_t ConstArg = ArgCI->getSExtValue();
561 
562     // Compose range checking error message.
563     std::string RangeErrMsg = IsUnaligned ? "byte" : "element";
564     RangeErrMsg += " number " + llvm::to_string(ConstArg);
565     RangeErrMsg += " is outside of the valid range [0, ";
566     RangeErrMsg += llvm::to_string(ValidMaxValue) + "]";
567 
568     // Issue error if third argument is not within the valid range.
569     if (ConstArg < 0 || ConstArg > ValidMaxValue)
570       CGM.Error(E->getExprLoc(), RangeErrMsg);
571 
572     // Input to vec_replace_elt is an element index, convert to byte index.
573     if (!IsUnaligned) {
574       ConstArg *= Is32bit ? 4 : 8;
575       // Fix the constant according to endianess.
576       if (getTarget().isLittleEndian())
577         ConstArg = (Is32bit ? 12 : 8) - ConstArg;
578     }
579 
580     ID = Is32bit ? Intrinsic::ppc_altivec_vinsw : Intrinsic::ppc_altivec_vinsd;
581     Op2 = ConstantInt::getSigned(Int32Ty, ConstArg);
582     // Casting input to vector int as per intrinsic definition.
583     Op0 =
584         Is32bit
585             ? Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(Int32Ty, 4))
586             : Builder.CreateBitCast(Op0,
587                                     llvm::FixedVectorType::get(Int64Ty, 2));
588     return Builder.CreateBitCast(
589         Builder.CreateCall(CGM.getIntrinsic(ID), {Op0, Op1, Op2}), ResultType);
590   }
591   case PPC::BI__builtin_altivec_vadduqm:
592   case PPC::BI__builtin_altivec_vsubuqm: {
593     Value *Op0 = EmitScalarExpr(E->getArg(0));
594     Value *Op1 = EmitScalarExpr(E->getArg(1));
595     llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128);
596     Op0 = Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(Int128Ty, 1));
597     Op1 = Builder.CreateBitCast(Op1, llvm::FixedVectorType::get(Int128Ty, 1));
598     if (BuiltinID == PPC::BI__builtin_altivec_vadduqm)
599       return Builder.CreateAdd(Op0, Op1, "vadduqm");
600     else
601       return Builder.CreateSub(Op0, Op1, "vsubuqm");
602   }
603   case PPC::BI__builtin_altivec_vaddcuq_c:
604   case PPC::BI__builtin_altivec_vsubcuq_c: {
605     SmallVector<Value *, 2> Ops;
606     Value *Op0 = EmitScalarExpr(E->getArg(0));
607     Value *Op1 = EmitScalarExpr(E->getArg(1));
608     llvm::Type *V1I128Ty = llvm::FixedVectorType::get(
609         llvm::IntegerType::get(getLLVMContext(), 128), 1);
610     Ops.push_back(Builder.CreateBitCast(Op0, V1I128Ty));
611     Ops.push_back(Builder.CreateBitCast(Op1, V1I128Ty));
612     ID = (BuiltinID == PPC::BI__builtin_altivec_vaddcuq_c)
613              ? Intrinsic::ppc_altivec_vaddcuq
614              : Intrinsic::ppc_altivec_vsubcuq;
615     return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
616   }
617   case PPC::BI__builtin_altivec_vaddeuqm_c:
618   case PPC::BI__builtin_altivec_vaddecuq_c:
619   case PPC::BI__builtin_altivec_vsubeuqm_c:
620   case PPC::BI__builtin_altivec_vsubecuq_c: {
621     SmallVector<Value *, 3> Ops;
622     Value *Op0 = EmitScalarExpr(E->getArg(0));
623     Value *Op1 = EmitScalarExpr(E->getArg(1));
624     Value *Op2 = EmitScalarExpr(E->getArg(2));
625     llvm::Type *V1I128Ty = llvm::FixedVectorType::get(
626         llvm::IntegerType::get(getLLVMContext(), 128), 1);
627     Ops.push_back(Builder.CreateBitCast(Op0, V1I128Ty));
628     Ops.push_back(Builder.CreateBitCast(Op1, V1I128Ty));
629     Ops.push_back(Builder.CreateBitCast(Op2, V1I128Ty));
630     switch (BuiltinID) {
631     default:
632       llvm_unreachable("Unsupported intrinsic!");
633     case PPC::BI__builtin_altivec_vaddeuqm_c:
634       ID = Intrinsic::ppc_altivec_vaddeuqm;
635       break;
636     case PPC::BI__builtin_altivec_vaddecuq_c:
637       ID = Intrinsic::ppc_altivec_vaddecuq;
638       break;
639     case PPC::BI__builtin_altivec_vsubeuqm_c:
640       ID = Intrinsic::ppc_altivec_vsubeuqm;
641       break;
642     case PPC::BI__builtin_altivec_vsubecuq_c:
643       ID = Intrinsic::ppc_altivec_vsubecuq;
644       break;
645     }
646     return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, "");
647   }
648   case PPC::BI__builtin_ppc_rldimi:
649   case PPC::BI__builtin_ppc_rlwimi: {
650     Value *Op0 = EmitScalarExpr(E->getArg(0));
651     Value *Op1 = EmitScalarExpr(E->getArg(1));
652     Value *Op2 = EmitScalarExpr(E->getArg(2));
653     Value *Op3 = EmitScalarExpr(E->getArg(3));
654     // rldimi is 64-bit instruction, expand the intrinsic before isel to
655     // leverage peephole and avoid legalization efforts.
656     if (BuiltinID == PPC::BI__builtin_ppc_rldimi &&
657         !getTarget().getTriple().isPPC64()) {
658       Function *F = CGM.getIntrinsic(Intrinsic::fshl, Op0->getType());
659       Op2 = Builder.CreateZExt(Op2, Int64Ty);
660       Value *Shift = Builder.CreateCall(F, {Op0, Op0, Op2});
661       return Builder.CreateOr(Builder.CreateAnd(Shift, Op3),
662                               Builder.CreateAnd(Op1, Builder.CreateNot(Op3)));
663     }
664     return Builder.CreateCall(
665         CGM.getIntrinsic(BuiltinID == PPC::BI__builtin_ppc_rldimi
666                              ? Intrinsic::ppc_rldimi
667                              : Intrinsic::ppc_rlwimi),
668         {Op0, Op1, Op2, Op3});
669   }
670   case PPC::BI__builtin_ppc_rlwnm: {
671     Value *Op0 = EmitScalarExpr(E->getArg(0));
672     Value *Op1 = EmitScalarExpr(E->getArg(1));
673     Value *Op2 = EmitScalarExpr(E->getArg(2));
674     return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_rlwnm),
675                               {Op0, Op1, Op2});
676   }
677   case PPC::BI__builtin_ppc_poppar4:
678   case PPC::BI__builtin_ppc_poppar8: {
679     Value *Op0 = EmitScalarExpr(E->getArg(0));
680     llvm::Type *ArgType = Op0->getType();
681     Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType);
682     Value *Tmp = Builder.CreateCall(F, Op0);
683 
684     llvm::Type *ResultType = ConvertType(E->getType());
685     Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1));
686     if (Result->getType() != ResultType)
687       Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
688                                      "cast");
689     return Result;
690   }
691   case PPC::BI__builtin_ppc_cmpb: {
692     Value *Op0 = EmitScalarExpr(E->getArg(0));
693     Value *Op1 = EmitScalarExpr(E->getArg(1));
694     if (getTarget().getTriple().isPPC64()) {
695       Function *F =
696           CGM.getIntrinsic(Intrinsic::ppc_cmpb, {Int64Ty, Int64Ty, Int64Ty});
697       return Builder.CreateCall(F, {Op0, Op1}, "cmpb");
698     }
699     // For 32 bit, emit the code as below:
700     // %conv = trunc i64 %a to i32
701     // %conv1 = trunc i64 %b to i32
702     // %shr = lshr i64 %a, 32
703     // %conv2 = trunc i64 %shr to i32
704     // %shr3 = lshr i64 %b, 32
705     // %conv4 = trunc i64 %shr3 to i32
706     // %0 = tail call i32 @llvm.ppc.cmpb32(i32 %conv, i32 %conv1)
707     // %conv5 = zext i32 %0 to i64
708     // %1 = tail call i32 @llvm.ppc.cmpb32(i32 %conv2, i32 %conv4)
709     // %conv614 = zext i32 %1 to i64
710     // %shl = shl nuw i64 %conv614, 32
711     // %or = or i64 %shl, %conv5
712     // ret i64 %or
713     Function *F =
714         CGM.getIntrinsic(Intrinsic::ppc_cmpb, {Int32Ty, Int32Ty, Int32Ty});
715     Value *ArgOneLo = Builder.CreateTrunc(Op0, Int32Ty);
716     Value *ArgTwoLo = Builder.CreateTrunc(Op1, Int32Ty);
717     Constant *ShiftAmt = ConstantInt::get(Int64Ty, 32);
718     Value *ArgOneHi =
719         Builder.CreateTrunc(Builder.CreateLShr(Op0, ShiftAmt), Int32Ty);
720     Value *ArgTwoHi =
721         Builder.CreateTrunc(Builder.CreateLShr(Op1, ShiftAmt), Int32Ty);
722     Value *ResLo = Builder.CreateZExt(
723         Builder.CreateCall(F, {ArgOneLo, ArgTwoLo}, "cmpb"), Int64Ty);
724     Value *ResHiShift = Builder.CreateZExt(
725         Builder.CreateCall(F, {ArgOneHi, ArgTwoHi}, "cmpb"), Int64Ty);
726     Value *ResHi = Builder.CreateShl(ResHiShift, ShiftAmt);
727     return Builder.CreateOr(ResLo, ResHi);
728   }
729   // Copy sign
730   case PPC::BI__builtin_vsx_xvcpsgnsp:
731   case PPC::BI__builtin_vsx_xvcpsgndp: {
732     llvm::Type *ResultType = ConvertType(E->getType());
733     Value *X = EmitScalarExpr(E->getArg(0));
734     Value *Y = EmitScalarExpr(E->getArg(1));
735     ID = Intrinsic::copysign;
736     llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
737     return Builder.CreateCall(F, {X, Y});
738   }
739   // Rounding/truncation
740   case PPC::BI__builtin_vsx_xvrspip:
741   case PPC::BI__builtin_vsx_xvrdpip:
742   case PPC::BI__builtin_vsx_xvrdpim:
743   case PPC::BI__builtin_vsx_xvrspim:
744   case PPC::BI__builtin_vsx_xvrdpi:
745   case PPC::BI__builtin_vsx_xvrspi:
746   case PPC::BI__builtin_vsx_xvrdpic:
747   case PPC::BI__builtin_vsx_xvrspic:
748   case PPC::BI__builtin_vsx_xvrdpiz:
749   case PPC::BI__builtin_vsx_xvrspiz: {
750     llvm::Type *ResultType = ConvertType(E->getType());
751     Value *X = EmitScalarExpr(E->getArg(0));
752     if (BuiltinID == PPC::BI__builtin_vsx_xvrdpim ||
753         BuiltinID == PPC::BI__builtin_vsx_xvrspim)
754       ID = Builder.getIsFPConstrained()
755                ? Intrinsic::experimental_constrained_floor
756                : Intrinsic::floor;
757     else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpi ||
758              BuiltinID == PPC::BI__builtin_vsx_xvrspi)
759       ID = Builder.getIsFPConstrained()
760                ? Intrinsic::experimental_constrained_round
761                : Intrinsic::round;
762     else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpic ||
763              BuiltinID == PPC::BI__builtin_vsx_xvrspic)
764       ID = Builder.getIsFPConstrained()
765                ? Intrinsic::experimental_constrained_rint
766                : Intrinsic::rint;
767     else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpip ||
768              BuiltinID == PPC::BI__builtin_vsx_xvrspip)
769       ID = Builder.getIsFPConstrained()
770                ? Intrinsic::experimental_constrained_ceil
771                : Intrinsic::ceil;
772     else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpiz ||
773              BuiltinID == PPC::BI__builtin_vsx_xvrspiz)
774       ID = Builder.getIsFPConstrained()
775                ? Intrinsic::experimental_constrained_trunc
776                : Intrinsic::trunc;
777     llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
778     return Builder.getIsFPConstrained() ? Builder.CreateConstrainedFPCall(F, X)
779                                         : Builder.CreateCall(F, X);
780   }
781 
782   // Absolute value
783   case PPC::BI__builtin_vsx_xvabsdp:
784   case PPC::BI__builtin_vsx_xvabssp: {
785     llvm::Type *ResultType = ConvertType(E->getType());
786     Value *X = EmitScalarExpr(E->getArg(0));
787     llvm::Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType);
788     return Builder.CreateCall(F, X);
789   }
790 
791   // Fastmath by default
792   case PPC::BI__builtin_ppc_recipdivf:
793   case PPC::BI__builtin_ppc_recipdivd:
794   case PPC::BI__builtin_ppc_rsqrtf:
795   case PPC::BI__builtin_ppc_rsqrtd: {
796     FastMathFlags FMF = Builder.getFastMathFlags();
797     Builder.getFastMathFlags().setFast();
798     llvm::Type *ResultType = ConvertType(E->getType());
799     Value *X = EmitScalarExpr(E->getArg(0));
800 
801     if (BuiltinID == PPC::BI__builtin_ppc_recipdivf ||
802         BuiltinID == PPC::BI__builtin_ppc_recipdivd) {
803       Value *Y = EmitScalarExpr(E->getArg(1));
804       Value *FDiv = Builder.CreateFDiv(X, Y, "recipdiv");
805       Builder.getFastMathFlags() &= (FMF);
806       return FDiv;
807     }
808     auto *One = ConstantFP::get(ResultType, 1.0);
809     llvm::Function *F = CGM.getIntrinsic(Intrinsic::sqrt, ResultType);
810     Value *FDiv = Builder.CreateFDiv(One, Builder.CreateCall(F, X), "rsqrt");
811     Builder.getFastMathFlags() &= (FMF);
812     return FDiv;
813   }
814   case PPC::BI__builtin_ppc_alignx: {
815     Value *Op0 = EmitScalarExpr(E->getArg(0));
816     Value *Op1 = EmitScalarExpr(E->getArg(1));
817     ConstantInt *AlignmentCI = cast<ConstantInt>(Op0);
818     if (AlignmentCI->getValue().ugt(llvm::Value::MaximumAlignment))
819       AlignmentCI = ConstantInt::get(AlignmentCI->getIntegerType(),
820                                      llvm::Value::MaximumAlignment);
821 
822     emitAlignmentAssumption(Op1, E->getArg(1),
823                             /*The expr loc is sufficient.*/ SourceLocation(),
824                             AlignmentCI, nullptr);
825     return Op1;
826   }
827   case PPC::BI__builtin_ppc_rdlam: {
828     Value *Op0 = EmitScalarExpr(E->getArg(0));
829     Value *Op1 = EmitScalarExpr(E->getArg(1));
830     Value *Op2 = EmitScalarExpr(E->getArg(2));
831     llvm::Type *Ty = Op0->getType();
832     Value *ShiftAmt = Builder.CreateIntCast(Op1, Ty, false);
833     Function *F = CGM.getIntrinsic(Intrinsic::fshl, Ty);
834     Value *Rotate = Builder.CreateCall(F, {Op0, Op0, ShiftAmt});
835     return Builder.CreateAnd(Rotate, Op2);
836   }
837   case PPC::BI__builtin_ppc_load2r: {
838     Function *F = CGM.getIntrinsic(Intrinsic::ppc_load2r);
839     Value *Op0 = EmitScalarExpr(E->getArg(0));
840     Value *LoadIntrinsic = Builder.CreateCall(F, {Op0});
841     return Builder.CreateTrunc(LoadIntrinsic, Int16Ty);
842   }
843   // FMA variations
844   case PPC::BI__builtin_ppc_fnmsub:
845   case PPC::BI__builtin_ppc_fnmsubs:
846   case PPC::BI__builtin_vsx_xvmaddadp:
847   case PPC::BI__builtin_vsx_xvmaddasp:
848   case PPC::BI__builtin_vsx_xvnmaddadp:
849   case PPC::BI__builtin_vsx_xvnmaddasp:
850   case PPC::BI__builtin_vsx_xvmsubadp:
851   case PPC::BI__builtin_vsx_xvmsubasp:
852   case PPC::BI__builtin_vsx_xvnmsubadp:
853   case PPC::BI__builtin_vsx_xvnmsubasp: {
854     llvm::Type *ResultType = ConvertType(E->getType());
855     Value *X = EmitScalarExpr(E->getArg(0));
856     Value *Y = EmitScalarExpr(E->getArg(1));
857     Value *Z = EmitScalarExpr(E->getArg(2));
858     llvm::Function *F;
859     if (Builder.getIsFPConstrained())
860       F = CGM.getIntrinsic(Intrinsic::experimental_constrained_fma, ResultType);
861     else
862       F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
863     switch (BuiltinID) {
864       case PPC::BI__builtin_vsx_xvmaddadp:
865       case PPC::BI__builtin_vsx_xvmaddasp:
866         if (Builder.getIsFPConstrained())
867           return Builder.CreateConstrainedFPCall(F, {X, Y, Z});
868         else
869           return Builder.CreateCall(F, {X, Y, Z});
870       case PPC::BI__builtin_vsx_xvnmaddadp:
871       case PPC::BI__builtin_vsx_xvnmaddasp:
872         if (Builder.getIsFPConstrained())
873           return Builder.CreateFNeg(
874               Builder.CreateConstrainedFPCall(F, {X, Y, Z}), "neg");
875         else
876           return Builder.CreateFNeg(Builder.CreateCall(F, {X, Y, Z}), "neg");
877       case PPC::BI__builtin_vsx_xvmsubadp:
878       case PPC::BI__builtin_vsx_xvmsubasp:
879         if (Builder.getIsFPConstrained())
880           return Builder.CreateConstrainedFPCall(
881               F, {X, Y, Builder.CreateFNeg(Z, "neg")});
882         else
883           return Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")});
884       case PPC::BI__builtin_ppc_fnmsub:
885       case PPC::BI__builtin_ppc_fnmsubs:
886       case PPC::BI__builtin_vsx_xvnmsubadp:
887       case PPC::BI__builtin_vsx_xvnmsubasp:
888         if (Builder.getIsFPConstrained())
889           return Builder.CreateFNeg(
890               Builder.CreateConstrainedFPCall(
891                   F, {X, Y, Builder.CreateFNeg(Z, "neg")}),
892               "neg");
893         else
894           return Builder.CreateCall(
895               CGM.getIntrinsic(Intrinsic::ppc_fnmsub, ResultType), {X, Y, Z});
896       }
897     llvm_unreachable("Unknown FMA operation");
898     return nullptr; // Suppress no-return warning
899   }
900 
901   case PPC::BI__builtin_vsx_insertword: {
902     Value *Op0 = EmitScalarExpr(E->getArg(0));
903     Value *Op1 = EmitScalarExpr(E->getArg(1));
904     Value *Op2 = EmitScalarExpr(E->getArg(2));
905     llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxinsertw);
906 
907     // Third argument is a compile time constant int. It must be clamped to
908     // to the range [0, 12].
909     ConstantInt *ArgCI = dyn_cast<ConstantInt>(Op2);
910     assert(ArgCI &&
911            "Third arg to xxinsertw intrinsic must be constant integer");
912     const int64_t MaxIndex = 12;
913     int64_t Index = std::clamp(ArgCI->getSExtValue(), (int64_t)0, MaxIndex);
914 
915     // The builtin semantics don't exactly match the xxinsertw instructions
916     // semantics (which ppc_vsx_xxinsertw follows). The builtin extracts the
917     // word from the first argument, and inserts it in the second argument. The
918     // instruction extracts the word from its second input register and inserts
919     // it into its first input register, so swap the first and second arguments.
920     std::swap(Op0, Op1);
921 
922     // Need to cast the second argument from a vector of unsigned int to a
923     // vector of long long.
924     Op1 = Builder.CreateBitCast(Op1, llvm::FixedVectorType::get(Int64Ty, 2));
925 
926     if (getTarget().isLittleEndian()) {
927       // Reverse the double words in the vector we will extract from.
928       Op0 = Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(Int64Ty, 2));
929       Op0 = Builder.CreateShuffleVector(Op0, Op0, {1, 0});
930 
931       // Reverse the index.
932       Index = MaxIndex - Index;
933     }
934 
935     // Intrinsic expects the first arg to be a vector of int.
936     Op0 = Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(Int32Ty, 4));
937     Op2 = ConstantInt::getSigned(Int32Ty, Index);
938     return Builder.CreateCall(F, {Op0, Op1, Op2});
939   }
940 
941   case PPC::BI__builtin_vsx_extractuword: {
942     Value *Op0 = EmitScalarExpr(E->getArg(0));
943     Value *Op1 = EmitScalarExpr(E->getArg(1));
944     llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxextractuw);
945 
946     // Intrinsic expects the first argument to be a vector of doublewords.
947     Op0 = Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(Int64Ty, 2));
948 
949     // The second argument is a compile time constant int that needs to
950     // be clamped to the range [0, 12].
951     ConstantInt *ArgCI = dyn_cast<ConstantInt>(Op1);
952     assert(ArgCI &&
953            "Second Arg to xxextractuw intrinsic must be a constant integer!");
954     const int64_t MaxIndex = 12;
955     int64_t Index = std::clamp(ArgCI->getSExtValue(), (int64_t)0, MaxIndex);
956 
957     if (getTarget().isLittleEndian()) {
958       // Reverse the index.
959       Index = MaxIndex - Index;
960       Op1 = ConstantInt::getSigned(Int32Ty, Index);
961 
962       // Emit the call, then reverse the double words of the results vector.
963       Value *Call = Builder.CreateCall(F, {Op0, Op1});
964 
965       Value *ShuffleCall =
966           Builder.CreateShuffleVector(Call, Call, {1, 0});
967       return ShuffleCall;
968     } else {
969       Op1 = ConstantInt::getSigned(Int32Ty, Index);
970       return Builder.CreateCall(F, {Op0, Op1});
971     }
972   }
973 
974   case PPC::BI__builtin_vsx_xxpermdi: {
975     Value *Op0 = EmitScalarExpr(E->getArg(0));
976     Value *Op1 = EmitScalarExpr(E->getArg(1));
977     Value *Op2 = EmitScalarExpr(E->getArg(2));
978     ConstantInt *ArgCI = dyn_cast<ConstantInt>(Op2);
979     assert(ArgCI && "Third arg must be constant integer!");
980 
981     unsigned Index = ArgCI->getZExtValue();
982     Op0 = Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(Int64Ty, 2));
983     Op1 = Builder.CreateBitCast(Op1, llvm::FixedVectorType::get(Int64Ty, 2));
984 
985     // Account for endianness by treating this as just a shuffle. So we use the
986     // same indices for both LE and BE in order to produce expected results in
987     // both cases.
988     int ElemIdx0 = (Index & 2) >> 1;
989     int ElemIdx1 = 2 + (Index & 1);
990 
991     int ShuffleElts[2] = {ElemIdx0, ElemIdx1};
992     Value *ShuffleCall = Builder.CreateShuffleVector(Op0, Op1, ShuffleElts);
993     QualType BIRetType = E->getType();
994     auto RetTy = ConvertType(BIRetType);
995     return Builder.CreateBitCast(ShuffleCall, RetTy);
996   }
997 
998   case PPC::BI__builtin_vsx_xxsldwi: {
999     Value *Op0 = EmitScalarExpr(E->getArg(0));
1000     Value *Op1 = EmitScalarExpr(E->getArg(1));
1001     Value *Op2 = EmitScalarExpr(E->getArg(2));
1002     ConstantInt *ArgCI = dyn_cast<ConstantInt>(Op2);
1003     assert(ArgCI && "Third argument must be a compile time constant");
1004     unsigned Index = ArgCI->getZExtValue() & 0x3;
1005     Op0 = Builder.CreateBitCast(Op0, llvm::FixedVectorType::get(Int32Ty, 4));
1006     Op1 = Builder.CreateBitCast(Op1, llvm::FixedVectorType::get(Int32Ty, 4));
1007 
1008     // Create a shuffle mask
1009     int ElemIdx0;
1010     int ElemIdx1;
1011     int ElemIdx2;
1012     int ElemIdx3;
1013     if (getTarget().isLittleEndian()) {
1014       // Little endian element N comes from element 8+N-Index of the
1015       // concatenated wide vector (of course, using modulo arithmetic on
1016       // the total number of elements).
1017       ElemIdx0 = (8 - Index) % 8;
1018       ElemIdx1 = (9 - Index) % 8;
1019       ElemIdx2 = (10 - Index) % 8;
1020       ElemIdx3 = (11 - Index) % 8;
1021     } else {
1022       // Big endian ElemIdx<N> = Index + N
1023       ElemIdx0 = Index;
1024       ElemIdx1 = Index + 1;
1025       ElemIdx2 = Index + 2;
1026       ElemIdx3 = Index + 3;
1027     }
1028 
1029     int ShuffleElts[4] = {ElemIdx0, ElemIdx1, ElemIdx2, ElemIdx3};
1030     Value *ShuffleCall = Builder.CreateShuffleVector(Op0, Op1, ShuffleElts);
1031     QualType BIRetType = E->getType();
1032     auto RetTy = ConvertType(BIRetType);
1033     return Builder.CreateBitCast(ShuffleCall, RetTy);
1034   }
1035 
1036   case PPC::BI__builtin_pack_vector_int128: {
1037     Value *Op0 = EmitScalarExpr(E->getArg(0));
1038     Value *Op1 = EmitScalarExpr(E->getArg(1));
1039     bool isLittleEndian = getTarget().isLittleEndian();
1040     Value *PoisonValue =
1041         llvm::PoisonValue::get(llvm::FixedVectorType::get(Op0->getType(), 2));
1042     Value *Res = Builder.CreateInsertElement(
1043         PoisonValue, Op0, (uint64_t)(isLittleEndian ? 1 : 0));
1044     Res = Builder.CreateInsertElement(Res, Op1,
1045                                       (uint64_t)(isLittleEndian ? 0 : 1));
1046     return Builder.CreateBitCast(Res, ConvertType(E->getType()));
1047   }
1048 
1049   case PPC::BI__builtin_unpack_vector_int128: {
1050     Value *Op0 = EmitScalarExpr(E->getArg(0));
1051     Value *Op1 = EmitScalarExpr(E->getArg(1));
1052     ConstantInt *Index = cast<ConstantInt>(Op1);
1053     Value *Unpacked = Builder.CreateBitCast(
1054         Op0, llvm::FixedVectorType::get(ConvertType(E->getType()), 2));
1055 
1056     if (getTarget().isLittleEndian())
1057       Index =
1058           ConstantInt::get(Index->getIntegerType(), 1 - Index->getZExtValue());
1059 
1060     return Builder.CreateExtractElement(Unpacked, Index);
1061   }
1062 
1063   case PPC::BI__builtin_ppc_sthcx: {
1064     llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_sthcx);
1065     Value *Op0 = EmitScalarExpr(E->getArg(0));
1066     Value *Op1 = Builder.CreateSExt(EmitScalarExpr(E->getArg(1)), Int32Ty);
1067     return Builder.CreateCall(F, {Op0, Op1});
1068   }
1069 
1070   // The PPC MMA builtins take a pointer to a __vector_quad as an argument.
1071   // Some of the MMA instructions accumulate their result into an existing
1072   // accumulator whereas the others generate a new accumulator. So we need to
1073   // use custom code generation to expand a builtin call with a pointer to a
1074   // load (if the corresponding instruction accumulates its result) followed by
1075   // the call to the intrinsic and a store of the result.
1076 #define CUSTOM_BUILTIN(Name, Intr, Types, Accumulate, Feature) \
1077   case PPC::BI__builtin_##Name:
1078 #include "clang/Basic/BuiltinsPPC.def"
1079   {
1080     SmallVector<Value *, 4> Ops;
1081     for (unsigned i = 0, e = E->getNumArgs(); i != e; i++)
1082       if (E->getArg(i)->getType()->isArrayType())
1083         Ops.push_back(
1084             EmitArrayToPointerDecay(E->getArg(i)).emitRawPointer(*this));
1085       else
1086         Ops.push_back(EmitScalarExpr(E->getArg(i)));
1087     // The first argument of these two builtins is a pointer used to store their
1088     // result. However, the llvm intrinsics return their result in multiple
1089     // return values. So, here we emit code extracting these values from the
1090     // intrinsic results and storing them using that pointer.
1091     if (BuiltinID == PPC::BI__builtin_mma_disassemble_acc ||
1092         BuiltinID == PPC::BI__builtin_vsx_disassemble_pair ||
1093         BuiltinID == PPC::BI__builtin_mma_disassemble_pair) {
1094       unsigned NumVecs = 2;
1095       auto Intrinsic = Intrinsic::ppc_vsx_disassemble_pair;
1096       if (BuiltinID == PPC::BI__builtin_mma_disassemble_acc) {
1097         NumVecs = 4;
1098         Intrinsic = Intrinsic::ppc_mma_disassemble_acc;
1099       }
1100       llvm::Function *F = CGM.getIntrinsic(Intrinsic);
1101       Address Addr = EmitPointerWithAlignment(E->getArg(1));
1102       Value *Vec = Builder.CreateLoad(Addr);
1103       Value *Call = Builder.CreateCall(F, {Vec});
1104       llvm::Type *VTy = llvm::FixedVectorType::get(Int8Ty, 16);
1105       Value *Ptr = Ops[0];
1106       for (unsigned i=0; i<NumVecs; i++) {
1107         Value *Vec = Builder.CreateExtractValue(Call, i);
1108         llvm::ConstantInt* Index = llvm::ConstantInt::get(IntTy, i);
1109         Value *GEP = Builder.CreateInBoundsGEP(VTy, Ptr, Index);
1110         Builder.CreateAlignedStore(Vec, GEP, MaybeAlign(16));
1111       }
1112       return Call;
1113     }
1114     if (BuiltinID == PPC::BI__builtin_vsx_build_pair ||
1115         BuiltinID == PPC::BI__builtin_mma_build_acc) {
1116       // Reverse the order of the operands for LE, so the
1117       // same builtin call can be used on both LE and BE
1118       // without the need for the programmer to swap operands.
1119       // The operands are reversed starting from the second argument,
1120       // the first operand is the pointer to the pair/accumulator
1121       // that is being built.
1122       if (getTarget().isLittleEndian())
1123         std::reverse(Ops.begin() + 1, Ops.end());
1124     }
1125     bool Accumulate;
1126     switch (BuiltinID) {
1127   #define CUSTOM_BUILTIN(Name, Intr, Types, Acc, Feature) \
1128     case PPC::BI__builtin_##Name: \
1129       ID = Intrinsic::ppc_##Intr; \
1130       Accumulate = Acc; \
1131       break;
1132   #include "clang/Basic/BuiltinsPPC.def"
1133     }
1134     if (BuiltinID == PPC::BI__builtin_vsx_lxvp ||
1135         BuiltinID == PPC::BI__builtin_vsx_stxvp ||
1136         BuiltinID == PPC::BI__builtin_mma_lxvp ||
1137         BuiltinID == PPC::BI__builtin_mma_stxvp) {
1138       if (BuiltinID == PPC::BI__builtin_vsx_lxvp ||
1139           BuiltinID == PPC::BI__builtin_mma_lxvp) {
1140         Ops[0] = Builder.CreateGEP(Int8Ty, Ops[1], Ops[0]);
1141       } else {
1142         Ops[1] = Builder.CreateGEP(Int8Ty, Ops[2], Ops[1]);
1143       }
1144       Ops.pop_back();
1145       llvm::Function *F = CGM.getIntrinsic(ID);
1146       return Builder.CreateCall(F, Ops, "");
1147     }
1148     SmallVector<Value*, 4> CallOps;
1149     if (Accumulate) {
1150       Address Addr = EmitPointerWithAlignment(E->getArg(0));
1151       Value *Acc = Builder.CreateLoad(Addr);
1152       CallOps.push_back(Acc);
1153     }
1154     for (unsigned i=1; i<Ops.size(); i++)
1155       CallOps.push_back(Ops[i]);
1156     llvm::Function *F = CGM.getIntrinsic(ID);
1157     Value *Call = Builder.CreateCall(F, CallOps);
1158     return Builder.CreateAlignedStore(Call, Ops[0], MaybeAlign());
1159   }
1160 
1161   case PPC::BI__builtin_ppc_compare_and_swap:
1162   case PPC::BI__builtin_ppc_compare_and_swaplp: {
1163     Address Addr = EmitPointerWithAlignment(E->getArg(0));
1164     Address OldValAddr = EmitPointerWithAlignment(E->getArg(1));
1165     Value *OldVal = Builder.CreateLoad(OldValAddr);
1166     QualType AtomicTy = E->getArg(0)->getType()->getPointeeType();
1167     LValue LV = MakeAddrLValue(Addr, AtomicTy);
1168     Value *Op2 = EmitScalarExpr(E->getArg(2));
1169     auto Pair = EmitAtomicCompareExchange(
1170         LV, RValue::get(OldVal), RValue::get(Op2), E->getExprLoc(),
1171         llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Monotonic, true);
1172     // Unlike c11's atomic_compare_exchange, according to
1173     // https://www.ibm.com/docs/en/xl-c-and-cpp-aix/16.1?topic=functions-compare-swap-compare-swaplp
1174     // > In either case, the contents of the memory location specified by addr
1175     // > are copied into the memory location specified by old_val_addr.
1176     // But it hasn't specified storing to OldValAddr is atomic or not and
1177     // which order to use. Now following XL's codegen, treat it as a normal
1178     // store.
1179     Value *LoadedVal = Pair.first.getScalarVal();
1180     Builder.CreateStore(LoadedVal, OldValAddr);
1181     return Builder.CreateZExt(Pair.second, Builder.getInt32Ty());
1182   }
1183   case PPC::BI__builtin_ppc_fetch_and_add:
1184   case PPC::BI__builtin_ppc_fetch_and_addlp: {
1185     return MakeBinaryAtomicValue(*this, AtomicRMWInst::Add, E,
1186                                  llvm::AtomicOrdering::Monotonic);
1187   }
1188   case PPC::BI__builtin_ppc_fetch_and_and:
1189   case PPC::BI__builtin_ppc_fetch_and_andlp: {
1190     return MakeBinaryAtomicValue(*this, AtomicRMWInst::And, E,
1191                                  llvm::AtomicOrdering::Monotonic);
1192   }
1193 
1194   case PPC::BI__builtin_ppc_fetch_and_or:
1195   case PPC::BI__builtin_ppc_fetch_and_orlp: {
1196     return MakeBinaryAtomicValue(*this, AtomicRMWInst::Or, E,
1197                                  llvm::AtomicOrdering::Monotonic);
1198   }
1199   case PPC::BI__builtin_ppc_fetch_and_swap:
1200   case PPC::BI__builtin_ppc_fetch_and_swaplp: {
1201     return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xchg, E,
1202                                  llvm::AtomicOrdering::Monotonic);
1203   }
1204   case PPC::BI__builtin_ppc_ldarx:
1205   case PPC::BI__builtin_ppc_lwarx:
1206   case PPC::BI__builtin_ppc_lharx:
1207   case PPC::BI__builtin_ppc_lbarx:
1208     return emitPPCLoadReserveIntrinsic(*this, BuiltinID, E);
1209   case PPC::BI__builtin_ppc_mfspr: {
1210     Value *Op0 = EmitScalarExpr(E->getArg(0));
1211     llvm::Type *RetType = CGM.getDataLayout().getTypeSizeInBits(VoidPtrTy) == 32
1212                               ? Int32Ty
1213                               : Int64Ty;
1214     Function *F = CGM.getIntrinsic(Intrinsic::ppc_mfspr, RetType);
1215     return Builder.CreateCall(F, {Op0});
1216   }
1217   case PPC::BI__builtin_ppc_mtspr: {
1218     Value *Op0 = EmitScalarExpr(E->getArg(0));
1219     Value *Op1 = EmitScalarExpr(E->getArg(1));
1220     llvm::Type *RetType = CGM.getDataLayout().getTypeSizeInBits(VoidPtrTy) == 32
1221                               ? Int32Ty
1222                               : Int64Ty;
1223     Function *F = CGM.getIntrinsic(Intrinsic::ppc_mtspr, RetType);
1224     return Builder.CreateCall(F, {Op0, Op1});
1225   }
1226   case PPC::BI__builtin_ppc_popcntb: {
1227     Value *ArgValue = EmitScalarExpr(E->getArg(0));
1228     llvm::Type *ArgType = ArgValue->getType();
1229     Function *F = CGM.getIntrinsic(Intrinsic::ppc_popcntb, {ArgType, ArgType});
1230     return Builder.CreateCall(F, {ArgValue}, "popcntb");
1231   }
1232   case PPC::BI__builtin_ppc_mtfsf: {
1233     // The builtin takes a uint32 that needs to be cast to an
1234     // f64 to be passed to the intrinsic.
1235     Value *Op0 = EmitScalarExpr(E->getArg(0));
1236     Value *Op1 = EmitScalarExpr(E->getArg(1));
1237     Value *Cast = Builder.CreateUIToFP(Op1, DoubleTy);
1238     llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_mtfsf);
1239     return Builder.CreateCall(F, {Op0, Cast}, "");
1240   }
1241 
1242   case PPC::BI__builtin_ppc_swdiv_nochk:
1243   case PPC::BI__builtin_ppc_swdivs_nochk: {
1244     Value *Op0 = EmitScalarExpr(E->getArg(0));
1245     Value *Op1 = EmitScalarExpr(E->getArg(1));
1246     FastMathFlags FMF = Builder.getFastMathFlags();
1247     Builder.getFastMathFlags().setFast();
1248     Value *FDiv = Builder.CreateFDiv(Op0, Op1, "swdiv_nochk");
1249     Builder.getFastMathFlags() &= (FMF);
1250     return FDiv;
1251   }
1252   case PPC::BI__builtin_ppc_fric:
1253     return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(
1254                            *this, E, Intrinsic::rint,
1255                            Intrinsic::experimental_constrained_rint))
1256         .getScalarVal();
1257   case PPC::BI__builtin_ppc_frim:
1258   case PPC::BI__builtin_ppc_frims:
1259     return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(
1260                            *this, E, Intrinsic::floor,
1261                            Intrinsic::experimental_constrained_floor))
1262         .getScalarVal();
1263   case PPC::BI__builtin_ppc_frin:
1264   case PPC::BI__builtin_ppc_frins:
1265     return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(
1266                            *this, E, Intrinsic::round,
1267                            Intrinsic::experimental_constrained_round))
1268         .getScalarVal();
1269   case PPC::BI__builtin_ppc_frip:
1270   case PPC::BI__builtin_ppc_frips:
1271     return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(
1272                            *this, E, Intrinsic::ceil,
1273                            Intrinsic::experimental_constrained_ceil))
1274         .getScalarVal();
1275   case PPC::BI__builtin_ppc_friz:
1276   case PPC::BI__builtin_ppc_frizs:
1277     return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(
1278                            *this, E, Intrinsic::trunc,
1279                            Intrinsic::experimental_constrained_trunc))
1280         .getScalarVal();
1281   case PPC::BI__builtin_ppc_fsqrt:
1282   case PPC::BI__builtin_ppc_fsqrts:
1283     return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(
1284                            *this, E, Intrinsic::sqrt,
1285                            Intrinsic::experimental_constrained_sqrt))
1286         .getScalarVal();
1287   case PPC::BI__builtin_ppc_test_data_class: {
1288     Value *Op0 = EmitScalarExpr(E->getArg(0));
1289     Value *Op1 = EmitScalarExpr(E->getArg(1));
1290     return Builder.CreateCall(
1291         CGM.getIntrinsic(Intrinsic::ppc_test_data_class, Op0->getType()),
1292         {Op0, Op1}, "test_data_class");
1293   }
1294   case PPC::BI__builtin_ppc_maxfe: {
1295     Value *Op0 = EmitScalarExpr(E->getArg(0));
1296     Value *Op1 = EmitScalarExpr(E->getArg(1));
1297     Value *Op2 = EmitScalarExpr(E->getArg(2));
1298     Value *Op3 = EmitScalarExpr(E->getArg(3));
1299     return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_maxfe),
1300                               {Op0, Op1, Op2, Op3});
1301   }
1302   case PPC::BI__builtin_ppc_maxfl: {
1303     Value *Op0 = EmitScalarExpr(E->getArg(0));
1304     Value *Op1 = EmitScalarExpr(E->getArg(1));
1305     Value *Op2 = EmitScalarExpr(E->getArg(2));
1306     Value *Op3 = EmitScalarExpr(E->getArg(3));
1307     return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_maxfl),
1308                               {Op0, Op1, Op2, Op3});
1309   }
1310   case PPC::BI__builtin_ppc_maxfs: {
1311     Value *Op0 = EmitScalarExpr(E->getArg(0));
1312     Value *Op1 = EmitScalarExpr(E->getArg(1));
1313     Value *Op2 = EmitScalarExpr(E->getArg(2));
1314     Value *Op3 = EmitScalarExpr(E->getArg(3));
1315     return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_maxfs),
1316                               {Op0, Op1, Op2, Op3});
1317   }
1318   case PPC::BI__builtin_ppc_minfe: {
1319     Value *Op0 = EmitScalarExpr(E->getArg(0));
1320     Value *Op1 = EmitScalarExpr(E->getArg(1));
1321     Value *Op2 = EmitScalarExpr(E->getArg(2));
1322     Value *Op3 = EmitScalarExpr(E->getArg(3));
1323     return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_minfe),
1324                               {Op0, Op1, Op2, Op3});
1325   }
1326   case PPC::BI__builtin_ppc_minfl: {
1327     Value *Op0 = EmitScalarExpr(E->getArg(0));
1328     Value *Op1 = EmitScalarExpr(E->getArg(1));
1329     Value *Op2 = EmitScalarExpr(E->getArg(2));
1330     Value *Op3 = EmitScalarExpr(E->getArg(3));
1331     return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_minfl),
1332                               {Op0, Op1, Op2, Op3});
1333   }
1334   case PPC::BI__builtin_ppc_minfs: {
1335     Value *Op0 = EmitScalarExpr(E->getArg(0));
1336     Value *Op1 = EmitScalarExpr(E->getArg(1));
1337     Value *Op2 = EmitScalarExpr(E->getArg(2));
1338     Value *Op3 = EmitScalarExpr(E->getArg(3));
1339     return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_minfs),
1340                               {Op0, Op1, Op2, Op3});
1341   }
1342   case PPC::BI__builtin_ppc_swdiv:
1343   case PPC::BI__builtin_ppc_swdivs: {
1344     Value *Op0 = EmitScalarExpr(E->getArg(0));
1345     Value *Op1 = EmitScalarExpr(E->getArg(1));
1346     return Builder.CreateFDiv(Op0, Op1, "swdiv");
1347   }
1348   case PPC::BI__builtin_ppc_set_fpscr_rn:
1349     return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_setrnd),
1350                               {EmitScalarExpr(E->getArg(0))});
1351   case PPC::BI__builtin_ppc_mffs:
1352     return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_readflm));
1353   }
1354 }
1355