diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2022-01-27 22:17:16 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2022-05-14 11:44:34 +0000 | 
| commit | 04eeddc0aa8e0a417a16eaf9d7d095207f4a8623 (patch) | |
| tree | 2a5d3b2fe5c852e91531d128d9177754572d5338 /contrib/llvm-project/clang/lib/CodeGen/CGStmt.cpp | |
| parent | 0eae32dcef82f6f06de6419a0d623d7def0cc8f6 (diff) | |
| parent | 6f8fc217eaa12bf657be1c6468ed9938d10168b3 (diff) | |
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/CGStmt.cpp')
| -rw-r--r-- | contrib/llvm-project/clang/lib/CodeGen/CGStmt.cpp | 132 | 
1 files changed, 72 insertions, 60 deletions
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGStmt.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGStmt.cpp index ef0068cd3b0c..520483bc08b6 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGStmt.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CGStmt.cpp @@ -2109,42 +2109,35 @@ AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr,    return (EarlyClobber ? "&{" : "{") + Register.str() + "}";  } -llvm::Value* -CodeGenFunction::EmitAsmInputLValue(const TargetInfo::ConstraintInfo &Info, -                                    LValue InputValue, QualType InputType, -                                    std::string &ConstraintStr, -                                    SourceLocation Loc) { -  llvm::Value *Arg; +std::pair<llvm::Value*, llvm::Type *> CodeGenFunction::EmitAsmInputLValue( +    const TargetInfo::ConstraintInfo &Info, LValue InputValue, +    QualType InputType, std::string &ConstraintStr, SourceLocation Loc) {    if (Info.allowsRegister() || !Info.allowsMemory()) { -    if (CodeGenFunction::hasScalarEvaluationKind(InputType)) { -      Arg = EmitLoadOfLValue(InputValue, Loc).getScalarVal(); -    } else { -      llvm::Type *Ty = ConvertType(InputType); -      uint64_t Size = CGM.getDataLayout().getTypeSizeInBits(Ty); -      if ((Size <= 64 && llvm::isPowerOf2_64(Size)) || -          getTargetHooks().isScalarizableAsmOperand(*this, Ty)) { -        Ty = llvm::IntegerType::get(getLLVMContext(), Size); -        Ty = llvm::PointerType::getUnqual(Ty); - -        Arg = Builder.CreateLoad( -            Builder.CreateBitCast(InputValue.getAddress(*this), Ty)); -      } else { -        Arg = InputValue.getPointer(*this); -        ConstraintStr += '*'; -      } +    if (CodeGenFunction::hasScalarEvaluationKind(InputType)) +      return {EmitLoadOfLValue(InputValue, Loc).getScalarVal(), nullptr}; + +    llvm::Type *Ty = ConvertType(InputType); +    uint64_t Size = CGM.getDataLayout().getTypeSizeInBits(Ty); +    if ((Size <= 64 && llvm::isPowerOf2_64(Size)) || +        getTargetHooks().isScalarizableAsmOperand(*this, Ty)) { +      Ty = llvm::IntegerType::get(getLLVMContext(), Size); +      Ty = llvm::PointerType::getUnqual(Ty); + +      return {Builder.CreateLoad( +                  Builder.CreateBitCast(InputValue.getAddress(*this), Ty)), +              nullptr};      } -  } else { -    Arg = InputValue.getPointer(*this); -    ConstraintStr += '*';    } -  return Arg; +  Address Addr = InputValue.getAddress(*this); +  ConstraintStr += '*'; +  return {Addr.getPointer(), Addr.getElementType()};  } -llvm::Value* CodeGenFunction::EmitAsmInput( -                                         const TargetInfo::ConstraintInfo &Info, -                                           const Expr *InputExpr, -                                           std::string &ConstraintStr) { +std::pair<llvm::Value *, llvm::Type *> +CodeGenFunction::EmitAsmInput(const TargetInfo::ConstraintInfo &Info, +                              const Expr *InputExpr, +                              std::string &ConstraintStr) {    // If this can't be a register or memory, i.e., has to be a constant    // (immediate or symbolic), try to emit it as such.    if (!Info.allowsRegister() && !Info.allowsMemory()) { @@ -2155,19 +2148,20 @@ llvm::Value* CodeGenFunction::EmitAsmInput(        llvm::APSInt IntResult;        if (EVResult.Val.toIntegralConstant(IntResult, InputExpr->getType(),                                            getContext())) -        return llvm::ConstantInt::get(getLLVMContext(), IntResult); +        return {llvm::ConstantInt::get(getLLVMContext(), IntResult), nullptr};      }      Expr::EvalResult Result;      if (InputExpr->EvaluateAsInt(Result, getContext())) -      return llvm::ConstantInt::get(getLLVMContext(), Result.Val.getInt()); +      return {llvm::ConstantInt::get(getLLVMContext(), Result.Val.getInt()), +              nullptr};    }    if (Info.allowsRegister() || !Info.allowsMemory())      if (CodeGenFunction::hasScalarEvaluationKind(InputExpr->getType())) -      return EmitScalarExpr(InputExpr); +      return {EmitScalarExpr(InputExpr), nullptr};    if (InputExpr->getStmtClass() == Expr::CXXThisExprClass) -    return EmitScalarExpr(InputExpr); +    return {EmitScalarExpr(InputExpr), nullptr};    InputExpr = InputExpr->IgnoreParenNoopCasts(getContext());    LValue Dest = EmitLValue(InputExpr);    return EmitAsmInputLValue(Info, Dest, InputExpr->getType(), ConstraintStr, @@ -2209,6 +2203,7 @@ static void UpdateAsmCallInst(llvm::CallBase &Result, bool HasSideEffect,                                bool HasUnwindClobber, bool ReadOnly,                                bool ReadNone, bool NoMerge, const AsmStmt &S,                                const std::vector<llvm::Type *> &ResultRegTypes, +                              const std::vector<llvm::Type *> &ArgElemTypes,                                CodeGenFunction &CGF,                                std::vector<llvm::Value *> &RegResults) {    if (!HasUnwindClobber) @@ -2224,6 +2219,15 @@ static void UpdateAsmCallInst(llvm::CallBase &Result, bool HasSideEffect,        Result.addFnAttr(llvm::Attribute::ReadOnly);    } +  // Add elementtype attribute for indirect constraints. +  for (auto Pair : llvm::enumerate(ArgElemTypes)) { +    if (Pair.value()) { +      auto Attr = llvm::Attribute::get( +          CGF.getLLVMContext(), llvm::Attribute::ElementType, Pair.value()); +      Result.addParamAttr(Pair.index(), Attr); +    } +  } +    // Slap the source location of the inline asm into a !srcloc metadata on the    // call.    if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(&S)) @@ -2291,6 +2295,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {    std::vector<llvm::Type *> ResultRegTypes;    std::vector<llvm::Type *> ResultTruncRegTypes;    std::vector<llvm::Type *> ArgTypes; +  std::vector<llvm::Type *> ArgElemTypes;    std::vector<llvm::Value*> Args;    llvm::BitVector ResultTypeRequiresCast; @@ -2298,6 +2303,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {    std::string InOutConstraints;    std::vector<llvm::Value*> InOutArgs;    std::vector<llvm::Type*> InOutArgTypes; +  std::vector<llvm::Type*> InOutArgElemTypes;    // Keep track of out constraints for tied input operand.    std::vector<std::string> OutputConstraints; @@ -2399,21 +2405,19 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {              std::max((uint64_t)LargestVectorWidth,                       VT->getPrimitiveSizeInBits().getKnownMinSize());      } else { -      llvm::Type *DestAddrTy = Dest.getAddress(*this).getType(); -      llvm::Value *DestPtr = Dest.getPointer(*this); +      Address DestAddr = Dest.getAddress(*this);        // Matrix types in memory are represented by arrays, but accessed through        // vector pointers, with the alignment specified on the access operation.        // For inline assembly, update pointer arguments to use vector pointers.        // Otherwise there will be a mis-match if the matrix is also an        // input-argument which is represented as vector. -      if (isa<MatrixType>(OutExpr->getType().getCanonicalType())) { -        DestAddrTy = llvm::PointerType::get( -            ConvertType(OutExpr->getType()), -            cast<llvm::PointerType>(DestAddrTy)->getAddressSpace()); -        DestPtr = Builder.CreateBitCast(DestPtr, DestAddrTy); -      } -      ArgTypes.push_back(DestAddrTy); -      Args.push_back(DestPtr); +      if (isa<MatrixType>(OutExpr->getType().getCanonicalType())) +        DestAddr = Builder.CreateElementBitCast( +            DestAddr, ConvertType(OutExpr->getType())); + +      ArgTypes.push_back(DestAddr.getType()); +      ArgElemTypes.push_back(DestAddr.getElementType()); +      Args.push_back(DestAddr.getPointer());        Constraints += "=*";        Constraints += OutputConstraint;        ReadOnly = ReadNone = false; @@ -2423,9 +2427,11 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {        InOutConstraints += ',';        const Expr *InputExpr = S.getOutputExpr(i); -      llvm::Value *Arg = EmitAsmInputLValue(Info, Dest, InputExpr->getType(), -                                            InOutConstraints, -                                            InputExpr->getExprLoc()); +      llvm::Value *Arg; +      llvm::Type *ArgElemType; +      std::tie(Arg, ArgElemType) = EmitAsmInputLValue( +          Info, Dest, InputExpr->getType(), InOutConstraints, +          InputExpr->getExprLoc());        if (llvm::Type* AdjTy =            getTargetHooks().adjustInlineAsmType(*this, OutputConstraint, @@ -2444,6 +2450,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {          InOutConstraints += OutputConstraint;        InOutArgTypes.push_back(Arg->getType()); +      InOutArgElemTypes.push_back(ArgElemType);        InOutArgs.push_back(Arg);      }    } @@ -2483,7 +2490,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {          getTarget(), CGM, S, false /* No EarlyClobber */);      std::string ReplaceConstraint (InputConstraint); -    llvm::Value *Arg = EmitAsmInput(Info, InputExpr, Constraints); +    llvm::Value *Arg; +    llvm::Type *ArgElemType; +    std::tie(Arg, ArgElemType) = EmitAsmInput(Info, InputExpr, Constraints);      // If this input argument is tied to a larger output result, extend the      // input to be the same size as the output.  The LLVM backend wants to see @@ -2528,10 +2537,19 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {                     VT->getPrimitiveSizeInBits().getKnownMinSize());      ArgTypes.push_back(Arg->getType()); +    ArgElemTypes.push_back(ArgElemType);      Args.push_back(Arg);      Constraints += InputConstraint;    } +  // Append the "input" part of inout constraints. +  for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) { +    ArgTypes.push_back(InOutArgTypes[i]); +    ArgElemTypes.push_back(InOutArgElemTypes[i]); +    Args.push_back(InOutArgs[i]); +  } +  Constraints += InOutConstraints; +    // Labels    SmallVector<llvm::BasicBlock *, 16> Transfer;    llvm::BasicBlock *Fallthrough = nullptr; @@ -2546,21 +2564,15 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {              llvm::BlockAddress::get(CurFn, Dest.getBlock());          Args.push_back(BA);          ArgTypes.push_back(BA->getType()); +        ArgElemTypes.push_back(nullptr);          if (!Constraints.empty())            Constraints += ','; -        Constraints += 'X'; +        Constraints += 'i';        }        Fallthrough = createBasicBlock("asm.fallthrough");      }    } -  // Append the "input" part of inout constraints last. -  for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) { -    ArgTypes.push_back(InOutArgTypes[i]); -    Args.push_back(InOutArgs[i]); -  } -  Constraints += InOutConstraints; -    bool HasUnwindClobber = false;    // Clobbers @@ -2647,18 +2659,18 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {      EmitBlock(Fallthrough);      UpdateAsmCallInst(cast<llvm::CallBase>(*Result), HasSideEffect, false,                        ReadOnly, ReadNone, InNoMergeAttributedStmt, S, -                      ResultRegTypes, *this, RegResults); +                      ResultRegTypes, ArgElemTypes, *this, RegResults);    } else if (HasUnwindClobber) {      llvm::CallBase *Result = EmitCallOrInvoke(IA, Args, "");      UpdateAsmCallInst(*Result, HasSideEffect, true, ReadOnly, ReadNone, -                      InNoMergeAttributedStmt, S, ResultRegTypes, *this, -                      RegResults); +                      InNoMergeAttributedStmt, S, ResultRegTypes, ArgElemTypes, +                      *this, RegResults);    } else {      llvm::CallInst *Result =          Builder.CreateCall(IA, Args, getBundlesForFunclet(IA));      UpdateAsmCallInst(cast<llvm::CallBase>(*Result), HasSideEffect, false,                        ReadOnly, ReadNone, InNoMergeAttributedStmt, S, -                      ResultRegTypes, *this, RegResults); +                      ResultRegTypes, ArgElemTypes, *this, RegResults);    }    assert(RegResults.size() == ResultRegTypes.size());  | 
