title: Reconstruction of High-Level Constructs in C file decompiled from LLVM IR
body: <p>I have <a href="https://gitlab.cs.fau.de/gene?sort=latest_activity_asc" rel="nofollow noreferrer">auto-generated</a> benchmark files in LLVM IR, but to extract loop bounds using another tool I need them in C. Converting to C is fairly simple using <a href="https://github.com/JuliaComputing/llvm-cbe" rel="nofollow noreferrer">llvm-cbe/Julia</a> (as suggested in comments in <a href="https://stackoverflow.com/questions/5180914/llvm-ir-back-to-human-readable-source-language">this post</a>) or <a href="https://github.com/staticafi/llvm2c" rel="nofollow noreferrer">llvm2c</a>. However, as far as I got, both tools represent the entire control flow with gotos, which makes the result a C program, but not much more usable. For example, this excerpt just represents some if/else constructs.</p>
  <pre><code>  gene_glob_input_variable = llvm_cbe_gene_arg;
    llvm_cbe_tmp__1 = gene_glob_input_variable;
    llvm_cbe_arith1 = llvm_cbe_tmp__1 ^ 253077109;
    llvm_cbe_tmp__2 = gene_glob_input_variable;
    if (((((llvm_cbe_tmp__2 &amp; -129) == 0u)&amp;1))) {
      goto llvm_cbe_br1_2e_then;
    } else {
      goto llvm_cbe_br1_2e_else_2e_wcp;
    }
  
  llvm_cbe_br1_2e_then:
    llvm_cbe_tmp__3 = gene_glob_input_variable;
    *((uint32_t*) alloca(sizeof(uint32_t))) = llvm_cbe_tmp__3;
    llvm_cbe_tmp__4 = gene_glob_input_variable;
    *((uint32_t*) alloca(sizeof(uint32_t))) = llvm_cbe_tmp__4;
    goto llvm_cbe_br1_2e_end_2e_wcp;
  
  llvm_cbe_br1_2e_else_2e_wcp:
    *(volatile uint16_t*)(&amp;cons0) = (((uint16_t)llvm_cbe_tmp__1));
    *(volatile uint16_t*)(&amp;cons0) = (((uint16_t)llvm_cbe_tmp__2));
    llvm_cbe_tmp__5 = gene_glob_input_variable;
    if (((((llvm_cbe_tmp__5 &amp; -1048577) != 0u)&amp;1))) {
      goto llvm_cbe_br2_2e_then_2e_wcp;
    } else {
      goto llvm_cbe_br2_2e_else;
    }
  </code></pre>
  <p>Is there a way to reconstruct if/else and for loops from C with gotos, or is there a way to use these tools to make that happen directly from .ll files? The constructs selected for generation in the benchmarks are fairly simple, so a solution with incomplete loop reconstruction would suffice. Thanks for any hint.</p>