[polly] r246941 - Add option -polly-codegen-add-debug-printing

Tobias Grosser via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 6 01:47:59 PDT 2015


Author: grosser
Date: Sun Sep  6 03:47:57 2015
New Revision: 246941

URL: http://llvm.org/viewvc/llvm-project?rev=246941&view=rev
Log:
Add option -polly-codegen-add-debug-printing

When this option is enabled, Polly will emit printf calls for each scalar
load/and store which dump the scalar value loaded/stored at run time.

This patch also refactors the RuntimeDebugBuilder to use variadic templates
when generating CPU printfs. As result, it now becomes easier to print
strings that consist of a set of arguments. Also, as a single printf
call is emitted, it is more likely for such strings to be emitted atomically
if executed multi-threaded.

Added:
    polly/trunk/test/Isl/CodeGen/RuntimeDebugBuilder/
    polly/trunk/test/Isl/CodeGen/RuntimeDebugBuilder/combine_different_values.c
    polly/trunk/test/Isl/CodeGen/RuntimeDebugBuilder/combine_different_values.ll
Modified:
    polly/trunk/include/polly/CodeGen/RuntimeDebugBuilder.h
    polly/trunk/lib/CodeGen/BlockGenerators.cpp
    polly/trunk/lib/CodeGen/RuntimeDebugBuilder.cpp

Modified: polly/trunk/include/polly/CodeGen/RuntimeDebugBuilder.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/CodeGen/RuntimeDebugBuilder.h?rev=246941&r1=246940&r2=246941&view=diff
==============================================================================
--- polly/trunk/include/polly/CodeGen/RuntimeDebugBuilder.h (original)
+++ polly/trunk/include/polly/CodeGen/RuntimeDebugBuilder.h Sun Sep  6 03:47:57 2015
@@ -30,30 +30,21 @@ namespace polly {
 /// run time.
 struct RuntimeDebugBuilder {
 
-  /// @brief Print a string to stdout.
+  /// @brief Print a set of LLVM-IR Values or StringRefs via printf
   ///
-  /// @param String The string to print.
-  static void createStrPrinter(PollyIRBuilder &Builder,
-                               const std::string &String);
-
-  /// @brief Print a value to stdout.
-  ///
-  /// @param V The value to print.
-  ///
-  /// @note Only integer, floating point and pointer values up to 64bit are
-  ///       supported.
-  static void createValuePrinter(PollyIRBuilder &Builder, llvm::Value *V);
-
-  /// @brief Add a call to the fflush function with no file pointer given.
-  ///
-  /// This call will flush all opened file pointers including stdout and stderr.
-  static void createFlush(PollyIRBuilder &Builder);
-
-  /// @brief Get a reference to the 'printf' function.
+  ///  This function emits a call to printf that will print the given arguments.
+  ///  It is useful for debugging CPU programs. All arguments given in this list
+  ///  will be automatically concatenated and the resulting string will be
+  ///  printed atomically. We also support ArrayRef arguments, which can be used
+  ///  to provide of id values.
   ///
-  /// If the current module does not yet contain a reference to printf, we
-  /// insert a reference to it. Otherwise the existing reference is returned.
-  static llvm::Function *getPrintF(PollyIRBuilder &Builder);
+  ///  @param Builder The builder used to emit the printer calls.
+  ///  @param Args    The list of values to print.
+  template <typename... Args>
+  static void createCPUPrinter(PollyIRBuilder &Builder, Args... args) {
+    std::vector<llvm::Value *> Vector;
+    createPrinter(Builder, /* CPU */ false, Vector, args...);
+  }
 
   /// @brief Print a set of LLVM-IR Values or StringRefs on an NVIDIA GPU.
   ///
@@ -69,52 +60,77 @@ struct RuntimeDebugBuilder {
   template <typename... Args>
   static void createGPUPrinter(PollyIRBuilder &Builder, Args... args) {
     std::vector<llvm::Value *> Vector;
-    createGPUVAPrinter(Builder, Vector, args...);
+    createPrinter(Builder, /* GPU */ true, Vector, args...);
   }
 
 private:
-  /// @brief GPU printing - Print a list of LLVM Values.
-  ///
-  static void createGPUVAPrinter(PollyIRBuilder &Builder,
-                                 llvm::ArrayRef<llvm::Value *> Values);
-
-  /// @brief GPU printing - Handle Values.
+  /// @brief Handle Values.
   template <typename... Args>
-  static void createGPUVAPrinter(PollyIRBuilder &Builder,
-                                 std::vector<llvm::Value *> &Values,
-                                 llvm::Value *Value, Args... args) {
+  static void createPrinter(PollyIRBuilder &Builder, bool UseGPU,
+                            std::vector<llvm::Value *> &Values,
+                            llvm::Value *Value, Args... args) {
     Values.push_back(Value);
-    createGPUVAPrinter(Builder, Values, args...);
+    createPrinter(Builder, UseGPU, Values, args...);
   }
 
-  /// @brief GPU printing - Handle StringRefs.
+  /// @brief Handle StringRefs.
   template <typename... Args>
-  static void createGPUVAPrinter(PollyIRBuilder &Builder,
-                                 std::vector<llvm::Value *> &Values,
-                                 llvm::StringRef String, Args... args) {
+  static void createPrinter(PollyIRBuilder &Builder, bool UseGPU,
+                            std::vector<llvm::Value *> &Values,
+                            llvm::StringRef String, Args... args) {
     Values.push_back(Builder.CreateGlobalStringPtr(String, "", 4));
-    createGPUVAPrinter(Builder, Values, args...);
+    createPrinter(Builder, UseGPU, Values, args...);
   }
 
-  /// @brief GPU printing - Handle ArrayRefs.
+  /// @brief Handle ArrayRefs.
   template <typename... Args>
-  static void createGPUVAPrinter(PollyIRBuilder &Builder,
-                                 std::vector<llvm::Value *> &Values,
-                                 llvm::ArrayRef<llvm::Value *> Array,
-                                 Args... args) {
+  static void createPrinter(PollyIRBuilder &Builder, bool UseGPU,
+                            std::vector<llvm::Value *> &Values,
+                            llvm::ArrayRef<llvm::Value *> Array, Args... args) {
     if (Array.size() >= 2)
-      createGPUVAPrinter(
-          Builder, Values, Array[0], " ",
-          llvm::ArrayRef<llvm::Value *>(&Array[1], Array.size() - 1), args...);
+      createPrinter(Builder, Values, Array[0], " ",
+                    llvm::ArrayRef<llvm::Value *>(&Array[1], Array.size() - 1),
+                    args...);
     else if (Array.size() == 1)
-      createGPUVAPrinter(Builder, Values, Array[0], args...);
+      createPrinter(Builder, UseGPU, Values, Array[0], args...);
     else
-      createGPUVAPrinter(Builder, Values, args...);
+      createPrinter(Builder, UseGPU, Values, args...);
   }
 
+  /// @brief Print a list of Values.
+  static void createPrinter(PollyIRBuilder &Builder, bool UseGPU,
+                            llvm::ArrayRef<llvm::Value *> Values);
+
+  /// @brief Print a list of Values on a GPU.
+  static void createGPUPrinterT(PollyIRBuilder &Builder,
+                                llvm::ArrayRef<llvm::Value *> Values);
+
+  /// @brief Print a list of Values on a CPU.
+  static void createCPUPrinterT(PollyIRBuilder &Builder,
+                                llvm::ArrayRef<llvm::Value *> Values);
+
+  /// @brief Get a reference to the 'printf' function.
+  ///
+  /// If the current module does not yet contain a reference to printf, we
+  /// insert a reference to it. Otherwise the existing reference is returned.
+  static llvm::Function *getPrintF(PollyIRBuilder &Builder);
+
+  /// @brief Call printf
+  ///
+  /// @param Builder The builder used to insert the code.
+  /// @param Format  The format string.
+  /// @param Values  The set of values to print.
+  static void createPrintF(PollyIRBuilder &Builder, std::string Format,
+                           llvm::ArrayRef<llvm::Value *> Values);
+
   /// @brief Get (and possibly insert) a vprintf declaration into the module.
   static llvm::Function *getVPrintF(PollyIRBuilder &Builder);
 
+  /// @brief Call fflush
+  ///
+  /// @parma Builder The builder used to insert the code.
+  static void createFlush(PollyIRBuilder &Builder);
+
   /// @brief Get (and possibly insert) a NVIDIA address space cast call.
   static llvm::Function *getAddressSpaceCast(PollyIRBuilder &Builder,
                                              unsigned Src, unsigned Dst,

Modified: polly/trunk/lib/CodeGen/BlockGenerators.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/BlockGenerators.cpp?rev=246941&r1=246940&r2=246941&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/BlockGenerators.cpp (original)
+++ polly/trunk/lib/CodeGen/BlockGenerators.cpp Sun Sep  6 03:47:57 2015
@@ -17,6 +17,7 @@
 #include "polly/CodeGen/BlockGenerators.h"
 #include "polly/CodeGen/CodeGeneration.h"
 #include "polly/CodeGen/IslExprBuilder.h"
+#include "polly/CodeGen/RuntimeDebugBuilder.h"
 #include "polly/Options.h"
 #include "polly/Support/GICHelper.h"
 #include "polly/Support/SCEVValidator.h"
@@ -41,6 +42,11 @@ static cl::opt<bool> Aligned("enable-pol
                              cl::Hidden, cl::init(false), cl::ZeroOrMore,
                              cl::cat(PollyCategory));
 
+static cl::opt<bool> DebugPrinting(
+    "polly-codegen-add-debug-printing",
+    cl::desc("Add printf calls that show the values loaded/stored."),
+    cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
+
 bool polly::canSynthesize(const Value *V, const llvm::LoopInfo *LI,
                           ScalarEvolution *SE, const Region *R) {
   if (!V || !SE->isSCEVable(V->getType()))
@@ -208,6 +214,11 @@ Value *BlockGenerator::generateScalarLoa
       generateLocationAccessed(Stmt, Load, Pointer, BBMap, LTS, NewAccesses);
   Value *ScalarLoad = Builder.CreateAlignedLoad(
       NewPointer, Load->getAlignment(), Load->getName() + "_p_scalar_");
+
+  if (DebugPrinting)
+    RuntimeDebugBuilder::createCPUPrinter(Builder, "Load from ", NewPointer,
+                                          ": ", ScalarLoad, "\n");
+
   return ScalarLoad;
 }
 
@@ -220,6 +231,10 @@ void BlockGenerator::generateScalarStore
   Value *ValueOperand = getNewValue(Stmt, Store->getValueOperand(), BBMap, LTS,
                                     getLoopForInst(Store));
 
+  if (DebugPrinting)
+    RuntimeDebugBuilder::createCPUPrinter(Builder, "Store to  ", NewPointer,
+                                          ": ", ValueOperand, "\n");
+
   Builder.CreateAlignedStore(ValueOperand, NewPointer, Store->getAlignment());
 }
 

Modified: polly/trunk/lib/CodeGen/RuntimeDebugBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/RuntimeDebugBuilder.cpp?rev=246941&r1=246940&r2=246941&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/RuntimeDebugBuilder.cpp (original)
+++ polly/trunk/lib/CodeGen/RuntimeDebugBuilder.cpp Sun Sep  6 03:47:57 2015
@@ -95,8 +95,72 @@ RuntimeDebugBuilder::getGPUThreadIdentif
   return Identifiers;
 }
 
-void RuntimeDebugBuilder::createGPUVAPrinter(PollyIRBuilder &Builder,
-                                             ArrayRef<Value *> Values) {
+void RuntimeDebugBuilder::createPrinter(PollyIRBuilder &Builder, bool IsGPU,
+                                        ArrayRef<Value *> Values) {
+  if (IsGPU)
+    createGPUPrinterT(Builder, Values);
+  else
+    createCPUPrinterT(Builder, Values);
+}
+
+static std::tuple<std::string, std::vector<Value *>>
+prepareValuesForPrinting(PollyIRBuilder &Builder, ArrayRef<Value *> Values) {
+  std::string FormatString;
+  std::vector<Value *> ValuesToPrint;
+
+  for (auto Val : Values) {
+    Type *Ty = Val->getType();
+
+    if (Ty->isFloatingPointTy()) {
+      if (!Ty->isDoubleTy())
+        Val = Builder.CreateFPExt(Val, Builder.getDoubleTy());
+    } else if (Ty->isIntegerTy()) {
+      if (Ty->getIntegerBitWidth() < 64)
+        Val = Builder.CreateSExt(Val, Builder.getInt64Ty());
+      else
+        assert(Ty->getIntegerBitWidth() &&
+               "Integer types larger 64 bit not supported");
+    } else if (isa<PointerType>(Ty)) {
+      if (Ty->getPointerElementType() == Builder.getInt8Ty() &&
+          Ty->getPointerAddressSpace() == 4) {
+        Val = Builder.CreateGEP(Val, Builder.getInt64(0));
+      } else {
+        Val = Builder.CreatePtrToInt(Val, Builder.getInt64Ty());
+      }
+    } else {
+      llvm_unreachable("Unknown type");
+    }
+
+    Ty = Val->getType();
+
+    if (Ty->isFloatingPointTy())
+      FormatString += "%f";
+    else if (Ty->isIntegerTy())
+      FormatString += "%ld";
+    else
+      FormatString += "%s";
+
+    ValuesToPrint.push_back(Val);
+  }
+
+  return std::make_tuple(FormatString, ValuesToPrint);
+}
+
+void RuntimeDebugBuilder::createCPUPrinterT(PollyIRBuilder &Builder,
+                                            ArrayRef<Value *> Values) {
+
+  std::string FormatString;
+  std::vector<Value *> ValuesToPrint;
+
+  std::tie(FormatString, ValuesToPrint) =
+      prepareValuesForPrinting(Builder, Values);
+
+  createPrintF(Builder, FormatString, ValuesToPrint);
+  createFlush(Builder);
+}
+
+void RuntimeDebugBuilder::createGPUPrinterT(PollyIRBuilder &Builder,
+                                            ArrayRef<Value *> Values) {
   std::string str;
 
   // Allocate print buffer (assuming 2*32 bit per element)
@@ -169,14 +233,24 @@ Function *RuntimeDebugBuilder::getPrintF
 
   if (!F) {
     GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
-    FunctionType *Ty =
-        FunctionType::get(Builder.getInt32Ty(), Builder.getInt8PtrTy(), true);
+    FunctionType *Ty = FunctionType::get(Builder.getInt32Ty(), true);
     F = Function::Create(Ty, Linkage, Name, M);
   }
 
   return F;
 }
 
+void RuntimeDebugBuilder::createPrintF(PollyIRBuilder &Builder,
+                                       std::string Format,
+                                       ArrayRef<Value *> Values) {
+  Value *FormatString = Builder.CreateGlobalStringPtr(Format);
+  std::vector<Value *> Arguments;
+
+  Arguments.push_back(FormatString);
+  Arguments.insert(Arguments.end(), Values.begin(), Values.end());
+  Builder.CreateCall(getPrintF(Builder), Arguments);
+}
+
 void RuntimeDebugBuilder::createFlush(PollyIRBuilder &Builder) {
   Module *M = Builder.GetInsertBlock()->getParent()->getParent();
   const char *Name = "fflush";
@@ -197,30 +271,3 @@ void RuntimeDebugBuilder::createFlush(Po
   // type to ensure that LLVM does not complain about mismatching types.
   Builder.CreateCall(F, Constant::getNullValue(F->arg_begin()->getType()));
 }
-
-void RuntimeDebugBuilder::createStrPrinter(PollyIRBuilder &Builder,
-                                           const std::string &String) {
-  Value *StringValue = Builder.CreateGlobalStringPtr(String);
-  Builder.CreateCall(getPrintF(Builder), StringValue);
-
-  createFlush(Builder);
-}
-
-void RuntimeDebugBuilder::createValuePrinter(PollyIRBuilder &Builder,
-                                             Value *V) {
-  const char *Format = nullptr;
-
-  Type *Ty = V->getType();
-  if (Ty->isIntegerTy())
-    Format = "%ld";
-  else if (Ty->isFloatingPointTy())
-    Format = "%lf";
-  else if (Ty->isPointerTy())
-    Format = "%p";
-
-  assert(Format && Ty->getPrimitiveSizeInBits() <= 64 && "Bad type to print.");
-
-  Value *FormatString = Builder.CreateGlobalStringPtr(Format);
-  Builder.CreateCall(getPrintF(Builder), {FormatString, V});
-  createFlush(Builder);
-}

Added: polly/trunk/test/Isl/CodeGen/RuntimeDebugBuilder/combine_different_values.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/RuntimeDebugBuilder/combine_different_values.c?rev=246941&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/RuntimeDebugBuilder/combine_different_values.c (added)
+++ polly/trunk/test/Isl/CodeGen/RuntimeDebugBuilder/combine_different_values.c Sun Sep  6 03:47:57 2015
@@ -0,0 +1,23 @@
+#define N 10
+void foo(float A[restrict], double B[restrict], char C[restrict],
+         int D[restrict], long E[restrict]) {
+  for (long i = 0; i < N; i++)
+    A[i] += B[i] + C[i] + D[i] + E[i];
+}
+
+int main() {
+  float A[N];
+  double B[N];
+  char C[N];
+  int D[N];
+  long E[N];
+
+  for (long i = 0; i < N; i++) {
+    __sync_synchronize();
+    A[i] = B[i] = C[i] = D[i] = E[i] = 42;
+  }
+
+  foo(A, B, C, D, E);
+
+  return A[8];
+}

Added: polly/trunk/test/Isl/CodeGen/RuntimeDebugBuilder/combine_different_values.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/RuntimeDebugBuilder/combine_different_values.ll?rev=246941&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/RuntimeDebugBuilder/combine_different_values.ll (added)
+++ polly/trunk/test/Isl/CodeGen/RuntimeDebugBuilder/combine_different_values.ll Sun Sep  6 03:47:57 2015
@@ -0,0 +1,179 @@
+; RUN: opt %loadPolly -polly-codegen -S -polly-detect-unprofitable \
+; RUN: -polly-no-early-exit -polly-codegen-add-debug-printing \
+; RUN: -polly-ignore-aliasing < %s | FileCheck %s
+
+;    #define N 10
+;    void foo(float A[restrict], double B[restrict], char C[restrict],
+;             int D[restrict], long E[restrict]) {
+;      for (long i = 0; i < N; i++)
+;        A[i] += B[i] + C[i] + D[i] + E[i];
+;    }
+;
+;    int main() {
+;      float A[N];
+;      double B[N];
+;      char C[N];
+;      int D[N];
+;      long E[N];
+;
+;      for (long i = 0; i < N; i++) {
+;        __sync_synchronize();
+;        A[i] = B[i] = C[i] = D[i] = E[i] = 42;
+;      }
+;
+;      foo(A, B, C, D, E);
+;
+;      return A[8];
+;    }
+
+; CHECK: @0 = private unnamed_addr addrspace(4) constant [11 x i8] c"Load from \00"
+; CHECK: @1 = private unnamed_addr addrspace(4) constant [3 x i8] c": \00"
+; CHECK: @2 = private unnamed_addr addrspace(4) constant [2 x i8] c"\0A\00"
+; CHECK: @3 = private unnamed_addr constant [12 x i8] c"%s%ld%s%f%s\00"
+; CHECK: @4 = private unnamed_addr addrspace(4) constant [11 x i8] c"Load from \00"
+; CHECK: @5 = private unnamed_addr addrspace(4) constant [3 x i8] c": \00"
+; CHECK: @6 = private unnamed_addr addrspace(4) constant [2 x i8] c"\0A\00"
+; CHECK: @7 = private unnamed_addr constant [13 x i8] c"%s%ld%s%ld%s\00"
+; CHECK: @8 = private unnamed_addr addrspace(4) constant [11 x i8] c"Load from \00"
+; CHECK: @9 = private unnamed_addr addrspace(4) constant [3 x i8] c": \00"
+; CHECK: @10 = private unnamed_addr addrspace(4) constant [2 x i8] c"\0A\00"
+; CHECK: @11 = private unnamed_addr constant [13 x i8] c"%s%ld%s%ld%s\00"
+; CHECK: @12 = private unnamed_addr addrspace(4) constant [11 x i8] c"Load from \00"
+; CHECK: @13 = private unnamed_addr addrspace(4) constant [3 x i8] c": \00"
+; CHECK: @14 = private unnamed_addr addrspace(4) constant [2 x i8] c"\0A\00"
+; CHECK: @15 = private unnamed_addr constant [13 x i8] c"%s%ld%s%ld%s\00"
+; CHECK: @16 = private unnamed_addr addrspace(4) constant [11 x i8] c"Load from \00"
+; CHECK: @17 = private unnamed_addr addrspace(4) constant [3 x i8] c": \00"
+; CHECK: @18 = private unnamed_addr addrspace(4) constant [2 x i8] c"\0A\00"
+; CHECK: @19 = private unnamed_addr constant [12 x i8] c"%s%ld%s%f%s\00"
+; CHECK: @20 = private unnamed_addr addrspace(4) constant [11 x i8] c"Store to  \00"
+; CHECK: @21 = private unnamed_addr addrspace(4) constant [3 x i8] c": \00"
+; CHECK: @22 = private unnamed_addr addrspace(4) constant [2 x i8] c"\0A\00"
+; CHECK: @23 = private unnamed_addr constant [12 x i8] c"%s%ld%s%f%s\00"
+
+; CHECK: %0 = ptrtoint double* %scevgep to i64
+; CHECK: %1 = call i32 (...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @3, i32 0, i32 0), i8 addrspace(4)* getelementptr inbounds ([11 x i8], [11 x i8] addrspace(4)* @0, i32 0, i32 0), i64 %0, i8 addrspace(4)* getelementptr inbounds ([3 x i8], [3 x i8] addrspace(4)* @1, i32 0, i32 0), double %tmp3_p_scalar_, i8 addrspace(4)* getelementptr inbounds ([2 x i8], [2 x i8] addrspace(4)* @2, i32 0, i32 0))
+; CHECK: %2 = call i32 @fflush(i8* null)
+; CHECK: %scevgep1 = getelementptr i8, i8* %C, i64 %polly.indvar
+; CHECK: %tmp5_p_scalar_ = load i8, i8* %scevgep1, align 1, !alias.scope !4, !noalias !7
+; CHECK: %3 = ptrtoint i8* %scevgep1 to i64
+; CHECK: %4 = sext i8 %tmp5_p_scalar_ to i64
+; CHECK: %5 = call i32 (...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @7, i32 0, i32 0), i8 addrspace(4)* getelementptr inbounds ([11 x i8], [11 x i8] addrspace(4)* @4, i32 0, i32 0), i64 %3, i8 addrspace(4)* getelementptr inbounds ([3 x i8], [3 x i8] addrspace(4)* @5, i32 0, i32 0), i64 %4, i8 addrspace(4)* getelementptr inbounds ([2 x i8], [2 x i8] addrspace(4)* @6, i32 0, i32 0))
+; CHECK: %6 = call i32 @fflush(i8* null)
+; CHECK: %p_tmp6 = sitofp i8 %tmp5_p_scalar_ to double
+; CHECK: %p_tmp7 = fadd double %tmp3_p_scalar_, %p_tmp6
+; CHECK: %scevgep2 = getelementptr i32, i32* %D, i64 %polly.indvar
+; CHECK: %tmp9_p_scalar_ = load i32, i32* %scevgep2, align 4, !alias.scope !5, !noalias !8
+; CHECK: %7 = ptrtoint i32* %scevgep2 to i64
+; CHECK: %8 = sext i32 %tmp9_p_scalar_ to i64
+; CHECK: %9 = call i32 (...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @11, i32 0, i32 0), i8 addrspace(4)* getelementptr inbounds ([11 x i8], [11 x i8] addrspace(4)* @8, i32 0, i32 0), i64 %7, i8 addrspace(4)* getelementptr inbounds ([3 x i8], [3 x i8] addrspace(4)* @9, i32 0, i32 0), i64 %8, i8 addrspace(4)* getelementptr inbounds ([2 x i8], [2 x i8] addrspace(4)* @10, i32 0, i32 0))
+; CHECK: %10 = call i32 @fflush(i8* null)
+; CHECK: %p_tmp10 = sitofp i32 %tmp9_p_scalar_ to double
+; CHECK: %p_tmp11 = fadd double %p_tmp7, %p_tmp10
+; CHECK: %scevgep3 = getelementptr i64, i64* %E, i64 %polly.indvar
+; CHECK: %tmp13_p_scalar_ = load i64, i64* %scevgep3, align 8, !alias.scope !3, !noalias !9
+; CHECK: %11 = ptrtoint i64* %scevgep3 to i64
+; CHECK: %12 = call i32 (...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @15, i32 0, i32 0), i8 addrspace(4)* getelementptr inbounds ([11 x i8], [11 x i8] addrspace(4)* @12, i32 0, i32 0), i64 %11, i8 addrspace(4)* getelementptr inbounds ([3 x i8], [3 x i8] addrspace(4)* @13, i32 0, i32 0), i64 %tmp13_p_scalar_, i8 addrspace(4)* getelementptr inbounds ([2 x i8], [2 x i8] addrspace(4)* @14, i32 0, i32 0))
+; CHECK: %13 = call i32 @fflush(i8* null)
+; CHECK: %p_tmp14 = sitofp i64 %tmp13_p_scalar_ to double
+; CHECK: %p_tmp15 = fadd double %p_tmp11, %p_tmp14
+; CHECK: %scevgep4 = getelementptr float, float* %A, i64 %polly.indvar
+; CHECK: %tmp17_p_scalar_ = load float, float* %scevgep4, align 4, !alias.scope !6, !noalias !10
+; CHECK: %14 = ptrtoint float* %scevgep4 to i64
+; CHECK: %15 = fpext float %tmp17_p_scalar_ to double
+; CHECK: %16 = call i32 (...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @19, i32 0, i32 0), i8 addrspace(4)* getelementptr inbounds ([11 x i8], [11 x i8] addrspace(4)* @16, i32 0, i32 0), i64 %14, i8 addrspace(4)* getelementptr inbounds ([3 x i8], [3 x i8] addrspace(4)* @17, i32 0, i32 0), double %15, i8 addrspace(4)* getelementptr inbounds ([2 x i8], [2 x i8] addrspace(4)* @18, i32 0, i32 0))
+; CHECK: %17 = call i32 @fflush(i8* null)
+; CHECK: %p_tmp18 = fpext float %tmp17_p_scalar_ to double
+; CHECK: %p_tmp19 = fadd double %p_tmp18, %p_tmp15
+; CHECK: %p_tmp20 = fptrunc double %p_tmp19 to float
+; CHECK: %18 = ptrtoint float* %scevgep4 to i64
+; CHECK: %19 = fpext float %p_tmp20 to double
+; CHECK: %20 = call i32 (...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @23, i32 0, i32 0), i8 addrspace(4)* getelementptr inbounds ([11 x i8], [11 x i8] addrspace(4)* @20, i32 0, i32 0), i64 %18, i8 addrspace(4)* getelementptr inbounds ([3 x i8], [3 x i8] addrspace(4)* @21, i32 0, i32 0), double %19, i8 addrspace(4)* getelementptr inbounds ([2 x i8], [2 x i8] addrspace(4)* @22, i32 0, i32 0))
+; CHECK: %21 = call i32 @fflush(i8* null)
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @foo(float* noalias %A, double* noalias %B, i8* noalias %C, i32* noalias %D, i64* noalias %E) {
+bb:
+  br label %bb1
+
+bb1:                                              ; preds = %bb21, %bb
+  %i.0 = phi i64 [ 0, %bb ], [ %tmp22, %bb21 ]
+  %exitcond = icmp ne i64 %i.0, 10
+  br i1 %exitcond, label %bb2, label %bb23
+
+bb2:                                              ; preds = %bb1
+  %tmp = getelementptr inbounds double, double* %B, i64 %i.0
+  %tmp3 = load double, double* %tmp, align 8
+  %tmp4 = getelementptr inbounds i8, i8* %C, i64 %i.0
+  %tmp5 = load i8, i8* %tmp4, align 1
+  %tmp6 = sitofp i8 %tmp5 to double
+  %tmp7 = fadd double %tmp3, %tmp6
+  %tmp8 = getelementptr inbounds i32, i32* %D, i64 %i.0
+  %tmp9 = load i32, i32* %tmp8, align 4
+  %tmp10 = sitofp i32 %tmp9 to double
+  %tmp11 = fadd double %tmp7, %tmp10
+  %tmp12 = getelementptr inbounds i64, i64* %E, i64 %i.0
+  %tmp13 = load i64, i64* %tmp12, align 8
+  %tmp14 = sitofp i64 %tmp13 to double
+  %tmp15 = fadd double %tmp11, %tmp14
+  %tmp16 = getelementptr inbounds float, float* %A, i64 %i.0
+  %tmp17 = load float, float* %tmp16, align 4
+  %tmp18 = fpext float %tmp17 to double
+  %tmp19 = fadd double %tmp18, %tmp15
+  %tmp20 = fptrunc double %tmp19 to float
+  store float %tmp20, float* %tmp16, align 4
+  br label %bb21
+
+bb21:                                             ; preds = %bb2
+  %tmp22 = add nsw i64 %i.0, 1
+  br label %bb1
+
+bb23:                                             ; preds = %bb1
+  ret void
+}
+
+define i32 @main() {
+bb:
+  %A = alloca [10 x float], align 16
+  %B = alloca [10 x double], align 16
+  %C = alloca [10 x i8], align 1
+  %D = alloca [10 x i32], align 16
+  %E = alloca [10 x i64], align 16
+  br label %bb1
+
+bb1:                                              ; preds = %bb7, %bb
+  %i.0 = phi i64 [ 0, %bb ], [ %tmp8, %bb7 ]
+  %exitcond = icmp ne i64 %i.0, 10
+  br i1 %exitcond, label %bb2, label %bb9
+
+bb2:                                              ; preds = %bb1
+  fence seq_cst
+  %tmp = getelementptr inbounds [10 x i64], [10 x i64]* %E, i64 0, i64 %i.0
+  store i64 42, i64* %tmp, align 8
+  %tmp3 = getelementptr inbounds [10 x i32], [10 x i32]* %D, i64 0, i64 %i.0
+  store i32 42, i32* %tmp3, align 4
+  %tmp4 = getelementptr inbounds [10 x i8], [10 x i8]* %C, i64 0, i64 %i.0
+  store i8 42, i8* %tmp4, align 1
+  %tmp5 = getelementptr inbounds [10 x double], [10 x double]* %B, i64 0, i64 %i.0
+  store double 4.200000e+01, double* %tmp5, align 8
+  %tmp6 = getelementptr inbounds [10 x float], [10 x float]* %A, i64 0, i64 %i.0
+  store float 4.200000e+01, float* %tmp6, align 4
+  br label %bb7
+
+bb7:                                              ; preds = %bb2
+  %tmp8 = add nsw i64 %i.0, 1
+  br label %bb1
+
+bb9:                                              ; preds = %bb1
+  %tmp10 = getelementptr inbounds [10 x float], [10 x float]* %A, i64 0, i64 0
+  %tmp11 = getelementptr inbounds [10 x double], [10 x double]* %B, i64 0, i64 0
+  %tmp12 = getelementptr inbounds [10 x i8], [10 x i8]* %C, i64 0, i64 0
+  %tmp13 = getelementptr inbounds [10 x i32], [10 x i32]* %D, i64 0, i64 0
+  %tmp14 = getelementptr inbounds [10 x i64], [10 x i64]* %E, i64 0, i64 0
+  call void @foo(float* %tmp10, double* %tmp11, i8* %tmp12, i32* %tmp13, i64* %tmp14)
+  %tmp15 = getelementptr inbounds [10 x float], [10 x float]* %A, i64 0, i64 8
+  %tmp16 = load float, float* %tmp15, align 16
+  %tmp17 = fptosi float %tmp16 to i32
+  ret i32 %tmp17
+}




More information about the llvm-commits mailing list