int main(int argc, const char *argv[]) {
  // CHECK-LABEL: define {{.*}} @main(
  // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]]
  if (argc < 2)
    return 1;

  const uint64_t MaxSize = 10000;
  static char Buffer[MaxSize];

  uint64_t Size = __llvm_profile_get_size_for_buffer();
  if (Size > MaxSize)
    return 1;
  int Write = __llvm_profile_write_buffer(Buffer);
  if (Write)
    return Write;

#ifdef CHECK_SYMBOLS
  // Don't write it out.  Since we're checking the symbols, we don't have libc
  // available.
  // Call merge function to make sure it does not bring in libc deps:
  __llvm_profile_merge_from_buffer(Buffer, Size);
  return 0;
#else
  // Actually write it out so we can FileCheck the output.
  FILE *File = fopen(argv[1], "w");
  if (!File)
    return 1;
  if (fwrite(Buffer, 1, Size, File) != Size)
    return 1;
  return fclose(File);
#endif
}
/* Read profile data in \c ProfileFile and merge with in-memory
   profile counters. Returns -1 if there is fatal error, otheriwse
   0 is returned.
*/
static int doProfileMerging(FILE *ProfileFile) {
    uint64_t ProfileFileSize;
    char *ProfileBuffer;

    if (fseek(ProfileFile, 0L, SEEK_END) == -1) {
        PROF_ERR("Unable to merge profile data, unable to get size: %s\n",
                 strerror(errno));
        return -1;
    }
    ProfileFileSize = ftell(ProfileFile);

    /* Restore file offset.  */
    if (fseek(ProfileFile, 0L, SEEK_SET) == -1) {
        PROF_ERR("Unable to merge profile data, unable to rewind: %s\n",
                 strerror(errno));
        return -1;
    }

    /* Nothing to merge.  */
    if (ProfileFileSize < sizeof(__llvm_profile_header)) {
        if (ProfileFileSize)
            PROF_WARN("Unable to merge profile data: %s\n",
                      "source profile file is too small.");
        return 0;
    }

    ProfileBuffer = mmap(NULL, ProfileFileSize, PROT_READ, MAP_SHARED | MAP_FILE,
                         fileno(ProfileFile), 0);
    if (ProfileBuffer == MAP_FAILED) {
        PROF_ERR("Unable to merge profile data, mmap failed: %s\n",
                 strerror(errno));
        return -1;
    }

    if (__llvm_profile_check_compatibility(ProfileBuffer, ProfileFileSize)) {
        (void)munmap(ProfileBuffer, ProfileFileSize);
        PROF_WARN("Unable to merge profile data: %s\n",
                  "source profile file is not compatible.");
        return 0;
    }

    /* Now start merging */
    __llvm_profile_merge_from_buffer(ProfileBuffer, ProfileFileSize);
    (void)munmap(ProfileBuffer, ProfileFileSize);

    return 0;
}
int main(int argc, const char *argv[]) {
  int i;
  if (argc < 2)
    return 1;

  const char *FileN = argv[1];
  __llvm_profile_set_filename(FileN);
  /* Start profiling. */
  __llvm_profile_reset_counters();
  foo(1);
  /* End profiling by freezing counters and
   * dump them to the file. */
  if (__llvm_profile_write_file())
    return 1;

  /* Read profile data into buffer. */
  FILE *File = fopen(FileN, "r");
  if (!File)
    return 1;
  fseek(File, 0, SEEK_END);
  uint64_t Size = ftell(File);
  fseek(File, 0, SEEK_SET);
  char *Buffer = (char *)malloc(Size);
  if (Size != fread(Buffer, 1, Size, File))
    return 1;
  fclose(File);

  /* Its profile will be discarded. */
  for (i = 0; i < 10; i++)
    bar();

  /* Start profiling again and merge in previously
     saved counters in buffer. */
  __llvm_profile_reset_counters();
  __llvm_profile_merge_from_buffer(Buffer, Size);
  foo(2);
  /* End profiling. */
  truncate(FileN, 0);
  if (__llvm_profile_write_file())
    return 1;

  /* Its profile will be discarded. */
  bar();

  return 0;
}