[PATCH] D137113: [Clang] refactor CodeGenFunction::EmitAsmStmt NFC

2023-02-16 Thread Nick Desaulniers via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb1bc723dfe97: [Clang] refactor CodeGenFunction::EmitAsmStmt 
NFC (authored by nickdesaulniers).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137113/new/

https://reviews.llvm.org/D137113

Files:
  clang/lib/CodeGen/CGStmt.cpp

Index: clang/lib/CodeGen/CGStmt.cpp
===
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -24,6 +24,7 @@
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/Assumptions.h"
@@ -2327,6 +2328,93 @@
   }
 }
 
+static void
+EmitAsmStores(CodeGenFunction , const AsmStmt ,
+  const llvm::ArrayRef RegResults,
+  const llvm::ArrayRef ResultRegTypes,
+  const llvm::ArrayRef ResultTruncRegTypes,
+  const llvm::ArrayRef ResultRegDests,
+  const llvm::ArrayRef ResultRegQualTys,
+  const llvm::BitVector ,
+  const llvm::BitVector ) {
+  CGBuilderTy  = CGF.Builder;
+  CodeGenModule  = CGF.CGM;
+  llvm::LLVMContext  = CGF.getLLVMContext();
+
+  assert(RegResults.size() == ResultRegTypes.size());
+  assert(RegResults.size() == ResultTruncRegTypes.size());
+  assert(RegResults.size() == ResultRegDests.size());
+  // ResultRegDests can be also populated by addReturnRegisterOutputs() above,
+  // in which case its size may grow.
+  assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());
+  assert(ResultRegIsFlagReg.size() <= ResultRegDests.size());
+
+  for (unsigned i = 0, e = RegResults.size(); i != e; ++i) {
+llvm::Value *Tmp = RegResults[i];
+llvm::Type *TruncTy = ResultTruncRegTypes[i];
+
+if ((i < ResultRegIsFlagReg.size()) && ResultRegIsFlagReg[i]) {
+  // Target must guarantee the Value `Tmp` here is lowered to a boolean
+  // value.
+  llvm::Constant *Two = llvm::ConstantInt::get(Tmp->getType(), 2);
+  llvm::Value *IsBooleanValue =
+  Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, Two);
+  llvm::Function *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);
+  Builder.CreateCall(FnAssume, IsBooleanValue);
+}
+
+// If the result type of the LLVM IR asm doesn't match the result type of
+// the expression, do the conversion.
+if (ResultRegTypes[i] != TruncTy) {
+
+  // Truncate the integer result to the right size, note that TruncTy can be
+  // a pointer.
+  if (TruncTy->isFloatingPointTy())
+Tmp = Builder.CreateFPTrunc(Tmp, TruncTy);
+  else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) {
+uint64_t ResSize = CGM.getDataLayout().getTypeSizeInBits(TruncTy);
+Tmp = Builder.CreateTrunc(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)ResSize));
+Tmp = Builder.CreateIntToPtr(Tmp, TruncTy);
+  } else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) {
+uint64_t TmpSize =
+CGM.getDataLayout().getTypeSizeInBits(Tmp->getType());
+Tmp = Builder.CreatePtrToInt(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)TmpSize));
+Tmp = Builder.CreateTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isIntegerTy()) {
+Tmp = Builder.CreateZExtOrTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isVectorTy()) {
+Tmp = Builder.CreateBitCast(Tmp, TruncTy);
+  }
+}
+
+LValue Dest = ResultRegDests[i];
+// ResultTypeRequiresCast elements correspond to the first
+// ResultTypeRequiresCast.size() elements of RegResults.
+if ((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) {
+  unsigned Size = CGF.getContext().getTypeSize(ResultRegQualTys[i]);
+  Address A =
+  Builder.CreateElementBitCast(Dest.getAddress(CGF), ResultRegTypes[i]);
+  if (CGF.getTargetHooks().isScalarizableAsmOperand(CGF, TruncTy)) {
+Builder.CreateStore(Tmp, A);
+continue;
+  }
+
+  QualType Ty =
+  CGF.getContext().getIntTypeForBitwidth(Size, /*Signed=*/false);
+  if (Ty.isNull()) {
+const Expr *OutExpr = S.getOutputExpr(i);
+CGM.getDiags().Report(OutExpr->getExprLoc(),
+  diag::err_store_value_to_reg);
+return;
+  }
+  Dest = CGF.MakeAddrLValue(A, Ty);
+}
+CGF.EmitStoreThroughLValue(RValue::get(Tmp), Dest);
+  }
+}
+
 void CodeGenFunction::EmitAsmStmt(const AsmStmt ) {
   // Pop all cleanup blocks at the end of the asm statement.
   CodeGenFunction::RunCleanupsScope Cleanups(*this);
@@ -2627,7 +2715,7 @@
   SmallVector Transfer;
   llvm::BasicBlock *Fallthrough = nullptr;
   bool IsGCCAsmGoto = false;
-  if (const auto *GS =  dyn_cast()) {
+  if 

[PATCH] D137113: [Clang] refactor CodeGenFunction::EmitAsmStmt NFC

2023-02-16 Thread Nick Desaulniers via Phabricator via cfe-commits
nickdesaulniers updated this revision to Diff 498209.
nickdesaulniers marked an inline comment as done.
nickdesaulniers added a comment.

- fix bugprone-argument-comment as per @shafik


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137113/new/

https://reviews.llvm.org/D137113

Files:
  clang/lib/CodeGen/CGStmt.cpp

Index: clang/lib/CodeGen/CGStmt.cpp
===
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -24,6 +24,7 @@
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/Assumptions.h"
@@ -2327,6 +2328,93 @@
   }
 }
 
+static void
+EmitAsmStores(CodeGenFunction , const AsmStmt ,
+  const llvm::ArrayRef RegResults,
+  const llvm::ArrayRef ResultRegTypes,
+  const llvm::ArrayRef ResultTruncRegTypes,
+  const llvm::ArrayRef ResultRegDests,
+  const llvm::ArrayRef ResultRegQualTys,
+  const llvm::BitVector ,
+  const llvm::BitVector ) {
+  CGBuilderTy  = CGF.Builder;
+  CodeGenModule  = CGF.CGM;
+  llvm::LLVMContext  = CGF.getLLVMContext();
+
+  assert(RegResults.size() == ResultRegTypes.size());
+  assert(RegResults.size() == ResultTruncRegTypes.size());
+  assert(RegResults.size() == ResultRegDests.size());
+  // ResultRegDests can be also populated by addReturnRegisterOutputs() above,
+  // in which case its size may grow.
+  assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());
+  assert(ResultRegIsFlagReg.size() <= ResultRegDests.size());
+
+  for (unsigned i = 0, e = RegResults.size(); i != e; ++i) {
+llvm::Value *Tmp = RegResults[i];
+llvm::Type *TruncTy = ResultTruncRegTypes[i];
+
+if ((i < ResultRegIsFlagReg.size()) && ResultRegIsFlagReg[i]) {
+  // Target must guarantee the Value `Tmp` here is lowered to a boolean
+  // value.
+  llvm::Constant *Two = llvm::ConstantInt::get(Tmp->getType(), 2);
+  llvm::Value *IsBooleanValue =
+  Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, Two);
+  llvm::Function *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);
+  Builder.CreateCall(FnAssume, IsBooleanValue);
+}
+
+// If the result type of the LLVM IR asm doesn't match the result type of
+// the expression, do the conversion.
+if (ResultRegTypes[i] != TruncTy) {
+
+  // Truncate the integer result to the right size, note that TruncTy can be
+  // a pointer.
+  if (TruncTy->isFloatingPointTy())
+Tmp = Builder.CreateFPTrunc(Tmp, TruncTy);
+  else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) {
+uint64_t ResSize = CGM.getDataLayout().getTypeSizeInBits(TruncTy);
+Tmp = Builder.CreateTrunc(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)ResSize));
+Tmp = Builder.CreateIntToPtr(Tmp, TruncTy);
+  } else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) {
+uint64_t TmpSize =
+CGM.getDataLayout().getTypeSizeInBits(Tmp->getType());
+Tmp = Builder.CreatePtrToInt(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)TmpSize));
+Tmp = Builder.CreateTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isIntegerTy()) {
+Tmp = Builder.CreateZExtOrTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isVectorTy()) {
+Tmp = Builder.CreateBitCast(Tmp, TruncTy);
+  }
+}
+
+LValue Dest = ResultRegDests[i];
+// ResultTypeRequiresCast elements correspond to the first
+// ResultTypeRequiresCast.size() elements of RegResults.
+if ((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) {
+  unsigned Size = CGF.getContext().getTypeSize(ResultRegQualTys[i]);
+  Address A =
+  Builder.CreateElementBitCast(Dest.getAddress(CGF), ResultRegTypes[i]);
+  if (CGF.getTargetHooks().isScalarizableAsmOperand(CGF, TruncTy)) {
+Builder.CreateStore(Tmp, A);
+continue;
+  }
+
+  QualType Ty =
+  CGF.getContext().getIntTypeForBitwidth(Size, /*Signed=*/false);
+  if (Ty.isNull()) {
+const Expr *OutExpr = S.getOutputExpr(i);
+CGM.getDiags().Report(OutExpr->getExprLoc(),
+  diag::err_store_value_to_reg);
+return;
+  }
+  Dest = CGF.MakeAddrLValue(A, Ty);
+}
+CGF.EmitStoreThroughLValue(RValue::get(Tmp), Dest);
+  }
+}
+
 void CodeGenFunction::EmitAsmStmt(const AsmStmt ) {
   // Pop all cleanup blocks at the end of the asm statement.
   CodeGenFunction::RunCleanupsScope Cleanups(*this);
@@ -2627,7 +2715,7 @@
   SmallVector Transfer;
   llvm::BasicBlock *Fallthrough = nullptr;
   bool IsGCCAsmGoto = false;
-  if (const auto *GS =  dyn_cast()) {
+  if (const auto *GS = dyn_cast()) {
 IsGCCAsmGoto = 

[PATCH] D137113: [Clang] refactor CodeGenFunction::EmitAsmStmt NFC

2023-02-16 Thread Nick Desaulniers via Phabricator via cfe-commits
nickdesaulniers updated this revision to Diff 498156.
nickdesaulniers added a comment.

- final rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137113/new/

https://reviews.llvm.org/D137113

Files:
  clang/lib/CodeGen/CGStmt.cpp

Index: clang/lib/CodeGen/CGStmt.cpp
===
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -24,6 +24,7 @@
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/Assumptions.h"
@@ -2327,6 +2328,93 @@
   }
 }
 
+static void
+EmitAsmStores(CodeGenFunction , const AsmStmt ,
+  const llvm::ArrayRef RegResults,
+  const llvm::ArrayRef ResultRegTypes,
+  const llvm::ArrayRef ResultTruncRegTypes,
+  const llvm::ArrayRef ResultRegDests,
+  const llvm::ArrayRef ResultRegQualTys,
+  const llvm::BitVector ,
+  const llvm::BitVector ) {
+  CGBuilderTy  = CGF.Builder;
+  CodeGenModule  = CGF.CGM;
+  llvm::LLVMContext  = CGF.getLLVMContext();
+
+  assert(RegResults.size() == ResultRegTypes.size());
+  assert(RegResults.size() == ResultTruncRegTypes.size());
+  assert(RegResults.size() == ResultRegDests.size());
+  // ResultRegDests can be also populated by addReturnRegisterOutputs() above,
+  // in which case its size may grow.
+  assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());
+  assert(ResultRegIsFlagReg.size() <= ResultRegDests.size());
+
+  for (unsigned i = 0, e = RegResults.size(); i != e; ++i) {
+llvm::Value *Tmp = RegResults[i];
+llvm::Type *TruncTy = ResultTruncRegTypes[i];
+
+if ((i < ResultRegIsFlagReg.size()) && ResultRegIsFlagReg[i]) {
+  // Target must guarantee the Value `Tmp` here is lowered to a boolean
+  // value.
+  llvm::Constant *Two = llvm::ConstantInt::get(Tmp->getType(), 2);
+  llvm::Value *IsBooleanValue =
+  Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, Two);
+  llvm::Function *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);
+  Builder.CreateCall(FnAssume, IsBooleanValue);
+}
+
+// If the result type of the LLVM IR asm doesn't match the result type of
+// the expression, do the conversion.
+if (ResultRegTypes[i] != TruncTy) {
+
+  // Truncate the integer result to the right size, note that TruncTy can be
+  // a pointer.
+  if (TruncTy->isFloatingPointTy())
+Tmp = Builder.CreateFPTrunc(Tmp, TruncTy);
+  else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) {
+uint64_t ResSize = CGM.getDataLayout().getTypeSizeInBits(TruncTy);
+Tmp = Builder.CreateTrunc(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)ResSize));
+Tmp = Builder.CreateIntToPtr(Tmp, TruncTy);
+  } else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) {
+uint64_t TmpSize =
+CGM.getDataLayout().getTypeSizeInBits(Tmp->getType());
+Tmp = Builder.CreatePtrToInt(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)TmpSize));
+Tmp = Builder.CreateTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isIntegerTy()) {
+Tmp = Builder.CreateZExtOrTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isVectorTy()) {
+Tmp = Builder.CreateBitCast(Tmp, TruncTy);
+  }
+}
+
+LValue Dest = ResultRegDests[i];
+// ResultTypeRequiresCast elements correspond to the first
+// ResultTypeRequiresCast.size() elements of RegResults.
+if ((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) {
+  unsigned Size = CGF.getContext().getTypeSize(ResultRegQualTys[i]);
+  Address A =
+  Builder.CreateElementBitCast(Dest.getAddress(CGF), ResultRegTypes[i]);
+  if (CGF.getTargetHooks().isScalarizableAsmOperand(CGF, TruncTy)) {
+Builder.CreateStore(Tmp, A);
+continue;
+  }
+
+  QualType Ty =
+  CGF.getContext().getIntTypeForBitwidth(Size, /*Signed*/ false);
+  if (Ty.isNull()) {
+const Expr *OutExpr = S.getOutputExpr(i);
+CGM.getDiags().Report(OutExpr->getExprLoc(),
+  diag::err_store_value_to_reg);
+return;
+  }
+  Dest = CGF.MakeAddrLValue(A, Ty);
+}
+CGF.EmitStoreThroughLValue(RValue::get(Tmp), Dest);
+  }
+}
+
 void CodeGenFunction::EmitAsmStmt(const AsmStmt ) {
   // Pop all cleanup blocks at the end of the asm statement.
   CodeGenFunction::RunCleanupsScope Cleanups(*this);
@@ -2627,7 +2715,7 @@
   SmallVector Transfer;
   llvm::BasicBlock *Fallthrough = nullptr;
   bool IsGCCAsmGoto = false;
-  if (const auto *GS =  dyn_cast()) {
+  if (const auto *GS = dyn_cast()) {
 IsGCCAsmGoto = GS->isAsmGoto();
 if (IsGCCAsmGoto) {
   for (const auto *E : GS->labels()) {
@@ 

[PATCH] D137113: [Clang] refactor CodeGenFunction::EmitAsmStmt NFC

2023-02-06 Thread Shafik Yaghmour via Phabricator via cfe-commits
shafik added inline comments.



Comment at: clang/lib/CodeGen/CGStmt.cpp:2405
+  QualType Ty =
+  CGF.getContext().getIntTypeForBitwidth(Size, /*Signed*/ false);
+  if (Ty.isNull()) {

To be consistent with 
[bugprone-argument-comment](https://clang.llvm.org/extra/clang-tidy/checks/bugprone/argument-comment.html)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137113/new/

https://reviews.llvm.org/D137113

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D137113: [Clang] refactor CodeGenFunction::EmitAsmStmt NFC

2023-02-06 Thread Nick Desaulniers via Phabricator via cfe-commits
nickdesaulniers updated this revision to Diff 495174.
nickdesaulniers added a comment.

- rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137113/new/

https://reviews.llvm.org/D137113

Files:
  clang/lib/CodeGen/CGStmt.cpp

Index: clang/lib/CodeGen/CGStmt.cpp
===
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -24,6 +24,7 @@
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/Assumptions.h"
@@ -2327,6 +2328,93 @@
   }
 }
 
+static void
+EmitAsmStores(CodeGenFunction , const AsmStmt ,
+  const llvm::ArrayRef RegResults,
+  const llvm::ArrayRef ResultRegTypes,
+  const llvm::ArrayRef ResultTruncRegTypes,
+  const llvm::ArrayRef ResultRegDests,
+  const llvm::ArrayRef ResultRegQualTys,
+  const llvm::BitVector ,
+  const llvm::BitVector ) {
+  CGBuilderTy  = CGF.Builder;
+  CodeGenModule  = CGF.CGM;
+  llvm::LLVMContext  = CGF.getLLVMContext();
+
+  assert(RegResults.size() == ResultRegTypes.size());
+  assert(RegResults.size() == ResultTruncRegTypes.size());
+  assert(RegResults.size() == ResultRegDests.size());
+  // ResultRegDests can be also populated by addReturnRegisterOutputs() above,
+  // in which case its size may grow.
+  assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());
+  assert(ResultRegIsFlagReg.size() <= ResultRegDests.size());
+
+  for (unsigned i = 0, e = RegResults.size(); i != e; ++i) {
+llvm::Value *Tmp = RegResults[i];
+llvm::Type *TruncTy = ResultTruncRegTypes[i];
+
+if ((i < ResultRegIsFlagReg.size()) && ResultRegIsFlagReg[i]) {
+  // Target must guarantee the Value `Tmp` here is lowered to a boolean
+  // value.
+  llvm::Constant *Two = llvm::ConstantInt::get(Tmp->getType(), 2);
+  llvm::Value *IsBooleanValue =
+  Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, Two);
+  llvm::Function *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);
+  Builder.CreateCall(FnAssume, IsBooleanValue);
+}
+
+// If the result type of the LLVM IR asm doesn't match the result type of
+// the expression, do the conversion.
+if (ResultRegTypes[i] != TruncTy) {
+
+  // Truncate the integer result to the right size, note that TruncTy can be
+  // a pointer.
+  if (TruncTy->isFloatingPointTy())
+Tmp = Builder.CreateFPTrunc(Tmp, TruncTy);
+  else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) {
+uint64_t ResSize = CGM.getDataLayout().getTypeSizeInBits(TruncTy);
+Tmp = Builder.CreateTrunc(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)ResSize));
+Tmp = Builder.CreateIntToPtr(Tmp, TruncTy);
+  } else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) {
+uint64_t TmpSize =
+CGM.getDataLayout().getTypeSizeInBits(Tmp->getType());
+Tmp = Builder.CreatePtrToInt(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)TmpSize));
+Tmp = Builder.CreateTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isIntegerTy()) {
+Tmp = Builder.CreateZExtOrTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isVectorTy()) {
+Tmp = Builder.CreateBitCast(Tmp, TruncTy);
+  }
+}
+
+LValue Dest = ResultRegDests[i];
+// ResultTypeRequiresCast elements correspond to the first
+// ResultTypeRequiresCast.size() elements of RegResults.
+if ((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) {
+  unsigned Size = CGF.getContext().getTypeSize(ResultRegQualTys[i]);
+  Address A =
+  Builder.CreateElementBitCast(Dest.getAddress(CGF), ResultRegTypes[i]);
+  if (CGF.getTargetHooks().isScalarizableAsmOperand(CGF, TruncTy)) {
+Builder.CreateStore(Tmp, A);
+continue;
+  }
+
+  QualType Ty =
+  CGF.getContext().getIntTypeForBitwidth(Size, /*Signed*/ false);
+  if (Ty.isNull()) {
+const Expr *OutExpr = S.getOutputExpr(i);
+CGM.getDiags().Report(OutExpr->getExprLoc(),
+  diag::err_store_value_to_reg);
+return;
+  }
+  Dest = CGF.MakeAddrLValue(A, Ty);
+}
+CGF.EmitStoreThroughLValue(RValue::get(Tmp), Dest);
+  }
+}
+
 void CodeGenFunction::EmitAsmStmt(const AsmStmt ) {
   // Pop all cleanup blocks at the end of the asm statement.
   CodeGenFunction::RunCleanupsScope Cleanups(*this);
@@ -2627,7 +2715,7 @@
   SmallVector Transfer;
   llvm::BasicBlock *Fallthrough = nullptr;
   bool IsGCCAsmGoto = false;
-  if (const auto *GS =  dyn_cast()) {
+  if (const auto *GS = dyn_cast()) {
 IsGCCAsmGoto = GS->isAsmGoto();
 if (IsGCCAsmGoto) {
   for (const auto *E : GS->labels()) {
@@ -2725,9 

[PATCH] D137113: [Clang] refactor CodeGenFunction::EmitAsmStmt NFC

2023-01-18 Thread Bill Wendling via Phabricator via cfe-commits
void accepted this revision.
void added a comment.

Still LGTM :-)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137113/new/

https://reviews.llvm.org/D137113

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D137113: [Clang] refactor CodeGenFunction::EmitAsmStmt NFC

2023-01-18 Thread Nick Desaulniers via Phabricator via cfe-commits
nickdesaulniers updated this revision to Diff 490245.
nickdesaulniers added a comment.

- rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137113/new/

https://reviews.llvm.org/D137113

Files:
  clang/lib/CodeGen/CGStmt.cpp

Index: clang/lib/CodeGen/CGStmt.cpp
===
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -24,6 +24,7 @@
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/Assumptions.h"
@@ -2327,6 +2328,93 @@
   }
 }
 
+static void
+EmitAsmStores(CodeGenFunction , const AsmStmt ,
+  const llvm::ArrayRef RegResults,
+  const llvm::ArrayRef ResultRegTypes,
+  const llvm::ArrayRef ResultTruncRegTypes,
+  const llvm::ArrayRef ResultRegDests,
+  const llvm::ArrayRef ResultRegQualTys,
+  const llvm::BitVector ,
+  const llvm::BitVector ) {
+  CGBuilderTy  = CGF.Builder;
+  CodeGenModule  = CGF.CGM;
+  llvm::LLVMContext  = CGF.getLLVMContext();
+
+  assert(RegResults.size() == ResultRegTypes.size());
+  assert(RegResults.size() == ResultTruncRegTypes.size());
+  assert(RegResults.size() == ResultRegDests.size());
+  // ResultRegDests can be also populated by addReturnRegisterOutputs() above,
+  // in which case its size may grow.
+  assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());
+  assert(ResultRegIsFlagReg.size() <= ResultRegDests.size());
+
+  for (unsigned i = 0, e = RegResults.size(); i != e; ++i) {
+llvm::Value *Tmp = RegResults[i];
+llvm::Type *TruncTy = ResultTruncRegTypes[i];
+
+if ((i < ResultRegIsFlagReg.size()) && ResultRegIsFlagReg[i]) {
+  // Target must guarantee the Value `Tmp` here is lowered to a boolean
+  // value.
+  llvm::Constant *Two = llvm::ConstantInt::get(Tmp->getType(), 2);
+  llvm::Value *IsBooleanValue =
+  Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, Two);
+  llvm::Function *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);
+  Builder.CreateCall(FnAssume, IsBooleanValue);
+}
+
+// If the result type of the LLVM IR asm doesn't match the result type of
+// the expression, do the conversion.
+if (ResultRegTypes[i] != TruncTy) {
+
+  // Truncate the integer result to the right size, note that TruncTy can be
+  // a pointer.
+  if (TruncTy->isFloatingPointTy())
+Tmp = Builder.CreateFPTrunc(Tmp, TruncTy);
+  else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) {
+uint64_t ResSize = CGM.getDataLayout().getTypeSizeInBits(TruncTy);
+Tmp = Builder.CreateTrunc(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)ResSize));
+Tmp = Builder.CreateIntToPtr(Tmp, TruncTy);
+  } else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) {
+uint64_t TmpSize =
+CGM.getDataLayout().getTypeSizeInBits(Tmp->getType());
+Tmp = Builder.CreatePtrToInt(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)TmpSize));
+Tmp = Builder.CreateTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isIntegerTy()) {
+Tmp = Builder.CreateZExtOrTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isVectorTy()) {
+Tmp = Builder.CreateBitCast(Tmp, TruncTy);
+  }
+}
+
+LValue Dest = ResultRegDests[i];
+// ResultTypeRequiresCast elements correspond to the first
+// ResultTypeRequiresCast.size() elements of RegResults.
+if ((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) {
+  unsigned Size = CGF.getContext().getTypeSize(ResultRegQualTys[i]);
+  Address A =
+  Builder.CreateElementBitCast(Dest.getAddress(CGF), ResultRegTypes[i]);
+  if (CGF.getTargetHooks().isScalarizableAsmOperand(CGF, TruncTy)) {
+Builder.CreateStore(Tmp, A);
+continue;
+  }
+
+  QualType Ty =
+  CGF.getContext().getIntTypeForBitwidth(Size, /*Signed*/ false);
+  if (Ty.isNull()) {
+const Expr *OutExpr = S.getOutputExpr(i);
+CGM.getDiags().Report(OutExpr->getExprLoc(),
+  diag::err_store_value_to_reg);
+return;
+  }
+  Dest = CGF.MakeAddrLValue(A, Ty);
+}
+CGF.EmitStoreThroughLValue(RValue::get(Tmp), Dest);
+  }
+}
+
 void CodeGenFunction::EmitAsmStmt(const AsmStmt ) {
   // Pop all cleanup blocks at the end of the asm statement.
   CodeGenFunction::RunCleanupsScope Cleanups(*this);
@@ -2627,7 +2715,7 @@
   SmallVector Transfer;
   llvm::BasicBlock *Fallthrough = nullptr;
   bool IsGCCAsmGoto = false;
-  if (const auto *GS =  dyn_cast()) {
+  if (const auto *GS = dyn_cast()) {
 IsGCCAsmGoto = GS->isAsmGoto();
 if (IsGCCAsmGoto) {
   for (const auto *E : GS->labels()) {
@@ -2725,9 

[PATCH] D137113: [Clang] refactor CodeGenFunction::EmitAsmStmt NFC

2023-01-10 Thread Nick Desaulniers via Phabricator via cfe-commits
nickdesaulniers updated this revision to Diff 487927.
nickdesaulniers added a comment.

- rebase, format


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137113/new/

https://reviews.llvm.org/D137113

Files:
  clang/lib/CodeGen/CGStmt.cpp

Index: clang/lib/CodeGen/CGStmt.cpp
===
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -24,6 +24,7 @@
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/Assumptions.h"
@@ -2326,6 +2327,93 @@
   }
 }
 
+static void
+EmitAsmStores(CodeGenFunction , const AsmStmt ,
+  const llvm::ArrayRef RegResults,
+  const llvm::ArrayRef ResultRegTypes,
+  const llvm::ArrayRef ResultTruncRegTypes,
+  const llvm::ArrayRef ResultRegDests,
+  const llvm::ArrayRef ResultRegQualTys,
+  const llvm::BitVector ,
+  const llvm::BitVector ) {
+  CGBuilderTy  = CGF.Builder;
+  CodeGenModule  = CGF.CGM;
+  llvm::LLVMContext  = CGF.getLLVMContext();
+
+  assert(RegResults.size() == ResultRegTypes.size());
+  assert(RegResults.size() == ResultTruncRegTypes.size());
+  assert(RegResults.size() == ResultRegDests.size());
+  // ResultRegDests can be also populated by addReturnRegisterOutputs() above,
+  // in which case its size may grow.
+  assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());
+  assert(ResultRegIsFlagReg.size() <= ResultRegDests.size());
+
+  for (unsigned i = 0, e = RegResults.size(); i != e; ++i) {
+llvm::Value *Tmp = RegResults[i];
+llvm::Type *TruncTy = ResultTruncRegTypes[i];
+
+if ((i < ResultRegIsFlagReg.size()) && ResultRegIsFlagReg[i]) {
+  // Target must guarantee the Value `Tmp` here is lowered to a boolean
+  // value.
+  llvm::Constant *Two = llvm::ConstantInt::get(Tmp->getType(), 2);
+  llvm::Value *IsBooleanValue =
+  Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, Two);
+  llvm::Function *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);
+  Builder.CreateCall(FnAssume, IsBooleanValue);
+}
+
+// If the result type of the LLVM IR asm doesn't match the result type of
+// the expression, do the conversion.
+if (ResultRegTypes[i] != TruncTy) {
+
+  // Truncate the integer result to the right size, note that TruncTy can be
+  // a pointer.
+  if (TruncTy->isFloatingPointTy())
+Tmp = Builder.CreateFPTrunc(Tmp, TruncTy);
+  else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) {
+uint64_t ResSize = CGM.getDataLayout().getTypeSizeInBits(TruncTy);
+Tmp = Builder.CreateTrunc(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)ResSize));
+Tmp = Builder.CreateIntToPtr(Tmp, TruncTy);
+  } else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) {
+uint64_t TmpSize =
+CGM.getDataLayout().getTypeSizeInBits(Tmp->getType());
+Tmp = Builder.CreatePtrToInt(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)TmpSize));
+Tmp = Builder.CreateTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isIntegerTy()) {
+Tmp = Builder.CreateZExtOrTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isVectorTy()) {
+Tmp = Builder.CreateBitCast(Tmp, TruncTy);
+  }
+}
+
+LValue Dest = ResultRegDests[i];
+// ResultTypeRequiresCast elements correspond to the first
+// ResultTypeRequiresCast.size() elements of RegResults.
+if ((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) {
+  unsigned Size = CGF.getContext().getTypeSize(ResultRegQualTys[i]);
+  Address A =
+  Builder.CreateElementBitCast(Dest.getAddress(CGF), ResultRegTypes[i]);
+  if (CGF.getTargetHooks().isScalarizableAsmOperand(CGF, TruncTy)) {
+Builder.CreateStore(Tmp, A);
+continue;
+  }
+
+  QualType Ty =
+  CGF.getContext().getIntTypeForBitwidth(Size, /*Signed*/ false);
+  if (Ty.isNull()) {
+const Expr *OutExpr = S.getOutputExpr(i);
+CGM.getDiags().Report(OutExpr->getExprLoc(),
+  diag::err_store_value_to_reg);
+return;
+  }
+  Dest = CGF.MakeAddrLValue(A, Ty);
+}
+CGF.EmitStoreThroughLValue(RValue::get(Tmp), Dest);
+  }
+}
+
 void CodeGenFunction::EmitAsmStmt(const AsmStmt ) {
   // Pop all cleanup blocks at the end of the asm statement.
   CodeGenFunction::RunCleanupsScope Cleanups(*this);
@@ -2626,7 +2714,7 @@
   SmallVector Transfer;
   llvm::BasicBlock *Fallthrough = nullptr;
   bool IsGCCAsmGoto = false;
-  if (const auto *GS =  dyn_cast()) {
+  if (const auto *GS = dyn_cast()) {
 IsGCCAsmGoto = GS->isAsmGoto();
 if (IsGCCAsmGoto) {
   for (const auto *E : GS->labels()) {
@@ 

[PATCH] D137113: [Clang] refactor CodeGenFunction::EmitAsmStmt NFC

2022-12-21 Thread Nick Desaulniers via Phabricator via cfe-commits
nickdesaulniers updated this revision to Diff 484672.
nickdesaulniers added a comment.

- rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137113/new/

https://reviews.llvm.org/D137113

Files:
  clang/lib/CodeGen/CGStmt.cpp

Index: clang/lib/CodeGen/CGStmt.cpp
===
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -24,6 +24,7 @@
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/Assumptions.h"
@@ -2326,6 +2327,93 @@
   }
 }
 
+static void
+EmitAsmStores(CodeGenFunction , const AsmStmt ,
+  const llvm::ArrayRef RegResults,
+  const llvm::ArrayRef ResultRegTypes,
+  const llvm::ArrayRef ResultTruncRegTypes,
+  const llvm::ArrayRef ResultRegDests,
+  const llvm::ArrayRef ResultRegQualTys,
+  const llvm::BitVector ,
+  const llvm::BitVector ) {
+  CGBuilderTy  = CGF.Builder;
+  CodeGenModule  = CGF.CGM;
+  llvm::LLVMContext  = CGF.getLLVMContext();
+
+  assert(RegResults.size() == ResultRegTypes.size());
+  assert(RegResults.size() == ResultTruncRegTypes.size());
+  assert(RegResults.size() == ResultRegDests.size());
+  // ResultRegDests can be also populated by addReturnRegisterOutputs() above,
+  // in which case its size may grow.
+  assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());
+  assert(ResultRegIsFlagReg.size() <= ResultRegDests.size());
+
+  for (unsigned i = 0, e = RegResults.size(); i != e; ++i) {
+llvm::Value *Tmp = RegResults[i];
+llvm::Type *TruncTy = ResultTruncRegTypes[i];
+
+if ((i < ResultRegIsFlagReg.size()) && ResultRegIsFlagReg[i]) {
+  // Target must guarantee the Value `Tmp` here is lowered to a boolean
+  // value.
+  llvm::Constant *Two = llvm::ConstantInt::get(Tmp->getType(), 2);
+  llvm::Value *IsBooleanValue =
+  Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, Two);
+  llvm::Function *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);
+  Builder.CreateCall(FnAssume, IsBooleanValue);
+}
+
+// If the result type of the LLVM IR asm doesn't match the result type of
+// the expression, do the conversion.
+if (ResultRegTypes[i] != TruncTy) {
+
+  // Truncate the integer result to the right size, note that TruncTy can be
+  // a pointer.
+  if (TruncTy->isFloatingPointTy())
+Tmp = Builder.CreateFPTrunc(Tmp, TruncTy);
+  else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) {
+uint64_t ResSize = CGM.getDataLayout().getTypeSizeInBits(TruncTy);
+Tmp = Builder.CreateTrunc(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)ResSize));
+Tmp = Builder.CreateIntToPtr(Tmp, TruncTy);
+  } else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) {
+uint64_t TmpSize =
+CGM.getDataLayout().getTypeSizeInBits(Tmp->getType());
+Tmp = Builder.CreatePtrToInt(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)TmpSize));
+Tmp = Builder.CreateTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isIntegerTy()) {
+Tmp = Builder.CreateZExtOrTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isVectorTy()) {
+Tmp = Builder.CreateBitCast(Tmp, TruncTy);
+  }
+}
+
+LValue Dest = ResultRegDests[i];
+// ResultTypeRequiresCast elements correspond to the first
+// ResultTypeRequiresCast.size() elements of RegResults.
+if ((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) {
+  unsigned Size = CGF.getContext().getTypeSize(ResultRegQualTys[i]);
+  Address A =
+  Builder.CreateElementBitCast(Dest.getAddress(CGF), ResultRegTypes[i]);
+  if (CGF.getTargetHooks().isScalarizableAsmOperand(CGF, TruncTy)) {
+Builder.CreateStore(Tmp, A);
+continue;
+  }
+
+  QualType Ty =
+  CGF.getContext().getIntTypeForBitwidth(Size, /*Signed*/ false);
+  if (Ty.isNull()) {
+const Expr *OutExpr = S.getOutputExpr(i);
+CGM.getDiags().Report(OutExpr->getExprLoc(),
+  diag::err_store_value_to_reg);
+return;
+  }
+  Dest = CGF.MakeAddrLValue(A, Ty);
+}
+CGF.EmitStoreThroughLValue(RValue::get(Tmp), Dest);
+  }
+}
+
 void CodeGenFunction::EmitAsmStmt(const AsmStmt ) {
   // Pop all cleanup blocks at the end of the asm statement.
   CodeGenFunction::RunCleanupsScope Cleanups(*this);
@@ -2626,7 +2714,7 @@
   SmallVector Transfer;
   llvm::BasicBlock *Fallthrough = nullptr;
   bool IsGCCAsmGoto = false;
-  if (const auto *GS =  dyn_cast()) {
+  if (const auto *GS = dyn_cast()) {
 IsGCCAsmGoto = GS->isAsmGoto();
 if (IsGCCAsmGoto) {
   for (const auto *E : GS->labels()) {
@@ -2724,9 

[PATCH] D137113: [Clang] refactor CodeGenFunction::EmitAsmStmt NFC

2022-12-07 Thread Nick Desaulniers via Phabricator via cfe-commits
nickdesaulniers updated this revision to Diff 480992.
nickdesaulniers added a comment.

- rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137113/new/

https://reviews.llvm.org/D137113

Files:
  clang/lib/CodeGen/CGStmt.cpp

Index: clang/lib/CodeGen/CGStmt.cpp
===
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -24,6 +24,7 @@
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/Assumptions.h"
@@ -2327,6 +2328,93 @@
   }
 }
 
+static void
+EmitAsmStores(CodeGenFunction , const AsmStmt ,
+  const llvm::ArrayRef RegResults,
+  const llvm::ArrayRef ResultRegTypes,
+  const llvm::ArrayRef ResultTruncRegTypes,
+  const llvm::ArrayRef ResultRegDests,
+  const llvm::ArrayRef ResultRegQualTys,
+  const llvm::BitVector ,
+  const llvm::BitVector ) {
+  CGBuilderTy  = CGF.Builder;
+  CodeGenModule  = CGF.CGM;
+  llvm::LLVMContext  = CGF.getLLVMContext();
+
+  assert(RegResults.size() == ResultRegTypes.size());
+  assert(RegResults.size() == ResultTruncRegTypes.size());
+  assert(RegResults.size() == ResultRegDests.size());
+  // ResultRegDests can be also populated by addReturnRegisterOutputs() above,
+  // in which case its size may grow.
+  assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());
+  assert(ResultRegIsFlagReg.size() <= ResultRegDests.size());
+
+  for (unsigned i = 0, e = RegResults.size(); i != e; ++i) {
+llvm::Value *Tmp = RegResults[i];
+llvm::Type *TruncTy = ResultTruncRegTypes[i];
+
+if ((i < ResultRegIsFlagReg.size()) && ResultRegIsFlagReg[i]) {
+  // Target must guarantee the Value `Tmp` here is lowered to a boolean
+  // value.
+  llvm::Constant *Two = llvm::ConstantInt::get(Tmp->getType(), 2);
+  llvm::Value *IsBooleanValue =
+  Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, Two);
+  llvm::Function *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);
+  Builder.CreateCall(FnAssume, IsBooleanValue);
+}
+
+// If the result type of the LLVM IR asm doesn't match the result type of
+// the expression, do the conversion.
+if (ResultRegTypes[i] != TruncTy) {
+
+  // Truncate the integer result to the right size, note that TruncTy can be
+  // a pointer.
+  if (TruncTy->isFloatingPointTy())
+Tmp = Builder.CreateFPTrunc(Tmp, TruncTy);
+  else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) {
+uint64_t ResSize = CGM.getDataLayout().getTypeSizeInBits(TruncTy);
+Tmp = Builder.CreateTrunc(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)ResSize));
+Tmp = Builder.CreateIntToPtr(Tmp, TruncTy);
+  } else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) {
+uint64_t TmpSize =
+CGM.getDataLayout().getTypeSizeInBits(Tmp->getType());
+Tmp = Builder.CreatePtrToInt(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)TmpSize));
+Tmp = Builder.CreateTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isIntegerTy()) {
+Tmp = Builder.CreateZExtOrTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isVectorTy()) {
+Tmp = Builder.CreateBitCast(Tmp, TruncTy);
+  }
+}
+
+LValue Dest = ResultRegDests[i];
+// ResultTypeRequiresCast elements correspond to the first
+// ResultTypeRequiresCast.size() elements of RegResults.
+if ((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) {
+  unsigned Size = CGF.getContext().getTypeSize(ResultRegQualTys[i]);
+  Address A =
+  Builder.CreateElementBitCast(Dest.getAddress(CGF), ResultRegTypes[i]);
+  if (CGF.getTargetHooks().isScalarizableAsmOperand(CGF, TruncTy)) {
+Builder.CreateStore(Tmp, A);
+continue;
+  }
+
+  QualType Ty =
+  CGF.getContext().getIntTypeForBitwidth(Size, /*Signed*/ false);
+  if (Ty.isNull()) {
+const Expr *OutExpr = S.getOutputExpr(i);
+CGM.getDiags().Report(OutExpr->getExprLoc(),
+  diag::err_store_value_to_reg);
+return;
+  }
+  Dest = CGF.MakeAddrLValue(A, Ty);
+}
+CGF.EmitStoreThroughLValue(RValue::get(Tmp), Dest);
+  }
+}
+
 void CodeGenFunction::EmitAsmStmt(const AsmStmt ) {
   // Pop all cleanup blocks at the end of the asm statement.
   CodeGenFunction::RunCleanupsScope Cleanups(*this);
@@ -2627,7 +2715,7 @@
   SmallVector Transfer;
   llvm::BasicBlock *Fallthrough = nullptr;
   bool IsGCCAsmGoto = false;
-  if (const auto *GS =  dyn_cast()) {
+  if (const auto *GS = dyn_cast()) {
 IsGCCAsmGoto = GS->isAsmGoto();
 if (IsGCCAsmGoto) {
   for (const auto *E : GS->labels()) {
@@ -2725,9 

[PATCH] D137113: [Clang] refactor CodeGenFunction::EmitAsmStmt NFC

2022-10-31 Thread Bill Wendling via Phabricator via cfe-commits
void accepted this revision.
void added a comment.
This revision is now accepted and ready to land.

Thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137113/new/

https://reviews.llvm.org/D137113

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D137113: [Clang] refactor CodeGenFunction::EmitAsmStmt NFC

2022-10-31 Thread Nick Desaulniers via Phabricator via cfe-commits
nickdesaulniers updated this revision to Diff 472132.
nickdesaulniers added a comment.

- move asserts


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137113/new/

https://reviews.llvm.org/D137113

Files:
  clang/lib/CodeGen/CGStmt.cpp

Index: clang/lib/CodeGen/CGStmt.cpp
===
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -24,6 +24,7 @@
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/Assumptions.h"
@@ -2325,6 +2326,93 @@
   }
 }
 
+static void
+EmitAsmStores(CodeGenFunction , const AsmStmt ,
+  const llvm::ArrayRef RegResults,
+  const llvm::ArrayRef ResultRegTypes,
+  const llvm::ArrayRef ResultTruncRegTypes,
+  const llvm::ArrayRef ResultRegDests,
+  const llvm::ArrayRef ResultRegQualTys,
+  const llvm::BitVector ,
+  const llvm::BitVector ) {
+  CGBuilderTy  = CGF.Builder;
+  CodeGenModule  = CGF.CGM;
+  llvm::LLVMContext  = CGF.getLLVMContext();
+
+  assert(RegResults.size() == ResultRegTypes.size());
+  assert(RegResults.size() == ResultTruncRegTypes.size());
+  assert(RegResults.size() == ResultRegDests.size());
+  // ResultRegDests can be also populated by addReturnRegisterOutputs() above,
+  // in which case its size may grow.
+  assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());
+  assert(ResultRegIsFlagReg.size() <= ResultRegDests.size());
+
+  for (unsigned i = 0, e = RegResults.size(); i != e; ++i) {
+llvm::Value *Tmp = RegResults[i];
+llvm::Type *TruncTy = ResultTruncRegTypes[i];
+
+if ((i < ResultRegIsFlagReg.size()) && ResultRegIsFlagReg[i]) {
+  // Target must guarantee the Value `Tmp` here is lowered to a boolean
+  // value.
+  llvm::Constant *Two = llvm::ConstantInt::get(Tmp->getType(), 2);
+  llvm::Value *IsBooleanValue =
+  Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, Two);
+  llvm::Function *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);
+  Builder.CreateCall(FnAssume, IsBooleanValue);
+}
+
+// If the result type of the LLVM IR asm doesn't match the result type of
+// the expression, do the conversion.
+if (ResultRegTypes[i] != TruncTy) {
+
+  // Truncate the integer result to the right size, note that TruncTy can be
+  // a pointer.
+  if (TruncTy->isFloatingPointTy())
+Tmp = Builder.CreateFPTrunc(Tmp, TruncTy);
+  else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) {
+uint64_t ResSize = CGM.getDataLayout().getTypeSizeInBits(TruncTy);
+Tmp = Builder.CreateTrunc(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)ResSize));
+Tmp = Builder.CreateIntToPtr(Tmp, TruncTy);
+  } else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) {
+uint64_t TmpSize =
+CGM.getDataLayout().getTypeSizeInBits(Tmp->getType());
+Tmp = Builder.CreatePtrToInt(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)TmpSize));
+Tmp = Builder.CreateTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isIntegerTy()) {
+Tmp = Builder.CreateZExtOrTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isVectorTy()) {
+Tmp = Builder.CreateBitCast(Tmp, TruncTy);
+  }
+}
+
+LValue Dest = ResultRegDests[i];
+// ResultTypeRequiresCast elements correspond to the first
+// ResultTypeRequiresCast.size() elements of RegResults.
+if ((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) {
+  unsigned Size = CGF.getContext().getTypeSize(ResultRegQualTys[i]);
+  Address A =
+  Builder.CreateElementBitCast(Dest.getAddress(CGF), ResultRegTypes[i]);
+  if (CGF.getTargetHooks().isScalarizableAsmOperand(CGF, TruncTy)) {
+Builder.CreateStore(Tmp, A);
+continue;
+  }
+
+  QualType Ty =
+  CGF.getContext().getIntTypeForBitwidth(Size, /*Signed*/ false);
+  if (Ty.isNull()) {
+const Expr *OutExpr = S.getOutputExpr(i);
+CGM.getDiags().Report(OutExpr->getExprLoc(),
+  diag::err_store_value_to_reg);
+return;
+  }
+  Dest = CGF.MakeAddrLValue(A, Ty);
+}
+CGF.EmitStoreThroughLValue(RValue::get(Tmp), Dest);
+  }
+}
+
 void CodeGenFunction::EmitAsmStmt(const AsmStmt ) {
   // Pop all cleanup blocks at the end of the asm statement.
   CodeGenFunction::RunCleanupsScope Cleanups(*this);
@@ -2625,7 +2713,7 @@
   SmallVector Transfer;
   llvm::BasicBlock *Fallthrough = nullptr;
   bool IsGCCAsmGoto = false;
-  if (const auto *GS =  dyn_cast()) {
+  if (const auto *GS = dyn_cast()) {
 IsGCCAsmGoto = GS->isAsmGoto();
 if (IsGCCAsmGoto) {
   for (const auto *E : GS->labels()) {
@@ 

[PATCH] D137113: [Clang] refactor CodeGenFunction::EmitAsmStmt NFC

2022-10-31 Thread Nick Desaulniers via Phabricator via cfe-commits
nickdesaulniers planned changes to this revision.
nickdesaulniers added a comment.

Let me move the asserts, too.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137113/new/

https://reviews.llvm.org/D137113

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D137113: [Clang] refactor CodeGenFunction::EmitAsmStmt NFC

2022-10-31 Thread Nick Desaulniers via Phabricator via cfe-commits
nickdesaulniers created this revision.
nickdesaulniers added reviewers: void, nikic, jyknight, efriedma, craig.topper.
Herald added a subscriber: StephenFan.
Herald added a project: All.
nickdesaulniers requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Prerequisite to further modifications in D136497 
.

Basically, there is a large body of code in CodeGenFunction::EmitAsmStmt
for emitting stores of outputs. We want to be able to repeat this logic,
for each destination of a callbr (rather than just the default
destination which is what the code currently does).

Also does some smaller cleanups like whitespace cleanups, and removing
pointless casts.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D137113

Files:
  clang/lib/CodeGen/CGStmt.cpp

Index: clang/lib/CodeGen/CGStmt.cpp
===
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -24,6 +24,7 @@
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/Assumptions.h"
@@ -2325,6 +2326,85 @@
   }
 }
 
+static void
+EmitAsmStores(CodeGenFunction , const AsmStmt ,
+  const llvm::ArrayRef RegResults,
+  const llvm::ArrayRef ResultRegTypes,
+  const llvm::ArrayRef ResultTruncRegTypes,
+  const llvm::ArrayRef ResultRegDests,
+  const llvm::ArrayRef ResultRegQualTys,
+  const llvm::BitVector ,
+  const llvm::BitVector ) {
+  CGBuilderTy  = CGF.Builder;
+  CodeGenModule  = CGF.CGM;
+  llvm::LLVMContext  = CGF.getLLVMContext();
+
+  for (unsigned i = 0, e = RegResults.size(); i != e; ++i) {
+llvm::Value *Tmp = RegResults[i];
+llvm::Type *TruncTy = ResultTruncRegTypes[i];
+
+if ((i < ResultRegIsFlagReg.size()) && ResultRegIsFlagReg[i]) {
+  // Target must guarantee the Value `Tmp` here is lowered to a boolean
+  // value.
+  llvm::Constant *Two = llvm::ConstantInt::get(Tmp->getType(), 2);
+  llvm::Value *IsBooleanValue =
+  Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, Two);
+  llvm::Function *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume);
+  Builder.CreateCall(FnAssume, IsBooleanValue);
+}
+
+// If the result type of the LLVM IR asm doesn't match the result type of
+// the expression, do the conversion.
+if (ResultRegTypes[i] != TruncTy) {
+
+  // Truncate the integer result to the right size, note that TruncTy can be
+  // a pointer.
+  if (TruncTy->isFloatingPointTy())
+Tmp = Builder.CreateFPTrunc(Tmp, TruncTy);
+  else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) {
+uint64_t ResSize = CGM.getDataLayout().getTypeSizeInBits(TruncTy);
+Tmp = Builder.CreateTrunc(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)ResSize));
+Tmp = Builder.CreateIntToPtr(Tmp, TruncTy);
+  } else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) {
+uint64_t TmpSize =
+CGM.getDataLayout().getTypeSizeInBits(Tmp->getType());
+Tmp = Builder.CreatePtrToInt(
+Tmp, llvm::IntegerType::get(CTX, (unsigned)TmpSize));
+Tmp = Builder.CreateTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isIntegerTy()) {
+Tmp = Builder.CreateZExtOrTrunc(Tmp, TruncTy);
+  } else if (TruncTy->isVectorTy()) {
+Tmp = Builder.CreateBitCast(Tmp, TruncTy);
+  }
+}
+
+LValue Dest = ResultRegDests[i];
+// ResultTypeRequiresCast elements correspond to the first
+// ResultTypeRequiresCast.size() elements of RegResults.
+if ((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) {
+  unsigned Size = CGF.getContext().getTypeSize(ResultRegQualTys[i]);
+  Address A =
+  Builder.CreateElementBitCast(Dest.getAddress(CGF), ResultRegTypes[i]);
+  if (CGF.getTargetHooks().isScalarizableAsmOperand(CGF, TruncTy)) {
+Builder.CreateStore(Tmp, A);
+continue;
+  }
+
+  QualType Ty =
+  CGF.getContext().getIntTypeForBitwidth(Size, /*Signed*/ false);
+  if (Ty.isNull()) {
+const Expr *OutExpr = S.getOutputExpr(i);
+CGM.getDiags().Report(OutExpr->getExprLoc(),
+  diag::err_store_value_to_reg);
+return;
+  }
+  Dest = CGF.MakeAddrLValue(A, Ty);
+}
+CGF.EmitStoreThroughLValue(RValue::get(Tmp), Dest);
+  }
+}
+
 void CodeGenFunction::EmitAsmStmt(const AsmStmt ) {
   // Pop all cleanup blocks at the end of the asm statement.
   CodeGenFunction::RunCleanupsScope Cleanups(*this);
@@ -2625,7 +2705,7 @@
   SmallVector Transfer;
   llvm::BasicBlock *Fallthrough = nullptr;
   bool IsGCCAsmGoto = false;
-  if (const auto *GS =