Disable constant folding for LLVM 10 C++ API

903 views Asked by At

I'm using the LLVM C++ API to write a compiler front-end for a subset of the C language. I've noticed the generated IR always has the constant folding optimization applied. But I want to disable this and get a faithful, unoptimized IR. Is there any way to do this?

Following is the code I'm using to generate IR from my module.

    llvm::verifyModule(kit.module, &llvm::outs());
    kit.module.print(llvm::outs(), nullptr);
    auto tirFile = "output.ir";
    error_code ec;
    llvm::raw_fd_ostream tirFileStream(tirFile, ec, llvm::sys::fs::F_None);
    kit.module.print(tirFileStream, nullptr);
    tirFileStream.flush();

Seems like the version of LLVM I'm using is LLVM 10.

sumit@HAL9001:~$ llvm-config --version
10.0.0

For example, when I run my compiler on the following C function

int arith() {
  return (10 - 10/3) << 3 | (23+8*12) & 1024;
}

It gets compiled to

define i32 @arith() {
entry:
  ret i32 56
}

The binary operations on constants are evaluated by the compiler itself, i.e. constant folding; it doesn't get translated to appropriate IR code.

2

There are 2 answers

1
Arpit Saxena On

Quoting from this link:

The way that the front-end lowers code to IR causes this sort of constant folding to happen even before any LLVM IR is generated. Essentially, when you do the AST traversal, you’re going to essentially see the following code get run:

IRBuilder<> Builder; Value *LHS = Builder.getInt32(2); 
Value *RHS = Builder.getInt32(4); // LHS and RHS are ConstantInt values because they’re constant expressions.
Value *Res = Builder.CreateMul(LHS,RHS); // Because LHS and RHS are constant values, the IRBuilder folds this to a constant expression.

This constant folding cannot be turned off. (I’m also assuming there’s no other constant folding going on at the Clang AST level).

0
Sergey Pastukhov On

In LLVM 11 you can use IRBuilder<llvm::NoFolder> instead of IRBuilder<>

I'm pretty sure it works for LLVM 10 too (although I haven't verified that).

Don't forget to #include <llvm/IR/NoFolder.h> :)