Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Clang automatically adding attributes to my functions?

I have a piece of code that I'm trying to turn into LLVM bitcode:

int main() {
    volatile double n = 0.45;
    for (int j = 0; j < 32; j++) {
        n *= j;
    }
    return 0;
}

I run the following command on it:

clang -O0 -S -emit-llvm TrainingCode/trainingCode.cpp -o TrainingCode/trainingCode.ll

to generate the following LLVM bitcode (take note of the 6th line, the one with "Function Attrs"):

; ModuleID = 'TrainingCode/trainingCode.cpp'
source_filename = "TrainingCode/trainingCode.cpp"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: noinline norecurse nounwind optnone uwtable
define i32 @main() #0 {
entry:
  %retval = alloca i32, align 4
  %n = alloca double, align 8
  %j = alloca i32, align 4
  store i32 0, i32* %retval, align 4
  store double 4.500000e-01, double* %n, align 8
  store i32 0, i32* %j, align 4
  br label %for.cond

for.cond:                                         ; preds = %for.inc, %entry
  %0 = load i32, i32* %j, align 4
  %cmp = icmp slt i32 %0, 32
  br i1 %cmp, label %for.body, label %for.end

for.body:                                         ; preds = %for.cond
  %1 = load i32, i32* %j, align 4
  %conv = sitofp i32 %1 to double
  %2 = load double, double* %n, align 8
  %mul = fmul double %2, %conv
  store double %mul, double* %n, align 8
  br label %for.inc

for.inc:                                          ; preds = %for.body
  %3 = load i32, i32* %j, align 4
  %inc = add nsw i32 %3, 1
  store i32 %inc, i32* %j, align 4
  br label %for.cond

for.end:                                          ; preds = %for.cond
  ret i32 0
}

attributes #0 = { noinline norecurse nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.module.flags = !{!0}
!llvm.ident = !{!1}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 5.0.0 (tags/RELEASE_500/final)"}

Why is clang adding the optnone attribute to main? I need LLVM to run various transformation passes on the bitcode and the optnone attribute is causing LLVM to skip over main... I need this attribute to not be added.

Compiling with -O1 seems to fix this, however this is unacceptable because I need Clang to give me unoptimized code. I want LLVM to optimize the unoptimized code given to me by Clang, but the presence of the optnone attribute is causing LLVM to not perform any optimizations.

like image 645
Farhad Avatar asked Nov 27 '17 05:11

Farhad


People also ask

Is Clang better than GCC?

Clang is much faster and uses far less memory than GCC. Clang aims to provide extremely clear and concise diagnostics (error and warning messages), and includes support for expressive diagnostics. GCC's warnings are sometimes acceptable, but are often confusing and it does not support expressive diagnostics.

What is __ attribute __ in C?

The __attribute__ directive is used to decorate a code declaration in C, C++ and Objective-C programming languages. This gives the declared code additional attributes that would help the compiler incorporate optimizations or elicit useful warnings to the consumer of that code.

What is Clang C++?

clang is a C, C++, and Objective-C compiler which encompasses preprocessing, parsing, optimization, code generation, assembly, and linking. Depending on which high-level mode setting is passed, Clang will stop before doing a full link.

What is LLVM Clang?

LLVM can serve as a background for compilers in multiple languages. Clang is a C, C++, Objective-C, or Objective-C++ compiler that is compiled in C++ based on LLVM and released under the Apache 2.0 license. Clang is mainly used to provide performance superior to that of GCC.


Video Answer


2 Answers

There are clang options to disable its optimization of the LLVM-IR. See https://reviews.llvm.org/D28047 for discussion of a patch that would change them, and @Anton's answer to this question for more about using it. Some or all of these options might be the right thing:

clang -O1 -mllvm -disable-llvm-optzns -disable-llvm-passes

(The resolution of that discussion was commit rL290392: Make '-disable-llvm-optzns' an alias for '-disable-llvm-passes', so current clang only needs one.)


Or there's the dumb way: A simple workaround is possible with sed (or your favourite text-processing tool).

You're only using this on compiler-generated code, so you don't have to worry about using regexes to parse free-form hand-written code. Thus you can match fixed formatting that the compiler always uses to make sure you operate only on the correct lines.

# tested and works on the .ll in your question
sed -i '/^; Function Attrs:\|^attributes #/ s/optnone //'   *.ll

Replaces the first occurence of optnone (with a trailing space) with the empty string, on lines that start with attributes # (the one that matters) or with ; Function Attrs: (the comment).

It's an s/// command controlled by a /foo\|bar/ address regex to select which lines it operates on.

sed -i rewrites the input file(s) in-place.

like image 170
Peter Cordes Avatar answered Oct 21 '22 04:10

Peter Cordes


This is expected. The -O0 output is not intended for further optimizations, some bits of IR are not emitted at all in order to reduce the compilation time.

So, you'd need to use -O1 -mllvm -disable-llvm-optzns if you want to get unoptimized IR that may be optimized later.

like image 20
Anton Korobeynikov Avatar answered Oct 21 '22 05:10

Anton Korobeynikov