I am new to clang and llvm. I'm trying to generate an unoptimized version of bit code from a c source code. I found that the generated bit code is having the constant folding optimization which I don't want.
I'm using this command: clang -O0 -Xclang -disable-O0-optnone test1.c -S -emit-llvm -o test1.ll
The test1.c file has the following code:
int test() {
int y;
y = 2 * 4;
return y;
}
The content of the test1.ll file:
Instead of generating an instruction for multiplying 2 and 4, it is directly storing the value 8 by doing the constant folding operation:
store i32 8, i32* %1, align 4
It would be really nice if someone kindly let me know what I am missing and how should I turn off the constant folding optimization. The version of llvm I am using is 6.0.0.
Thank you.
It would be really nice if someone kindly let me know what I am missing and how should I turn off the constant folding optimization. The version of llvm I am using is 6.0.0.
It is a Clang feature and can't be turned off even with -O0. To workaround this try making variables global, pass them as parameters to the function, or just write the IR manually.
Related
I have a very simple C++ code (it was a large one, but I stripped it to the essentials), but it's failing to compile. I'm providing all the details below.
The code
#include <vector>
const int SIZE = 43691;
std::vector<int> v[SIZE];
int main() {
return 0;
}
Compilation command: g++ -std=c++17 code.cpp -o code
Compilation error:
/var/folders/l5/mcv9tnkx66l65t30ypt260r00000gn/T//ccAtIuZq.s:449:29: error: unexpected token in '.section' directive
.section .data.rel.ro.local
^
GCC version: gcc version 12.1.0 (Homebrew GCC 12.1.0_1)
Operating system: MacOS Monterey, version 12.3, 64bit architecture (M1)
My findings and remarks:
The constant SIZE isn't random here. I tried many different values, and SIZE = 43691 is the first one that causes the compilation error.
My guess is that it is caused by stack overflow. So I tried to compile using the flag -Wl,-stack_size,0x20000000, and also tried ulimit -s 65520. But neither of them has any effect on the issue, the code still fails to compile once SIZE exceeds 43690.
I also calculated the amount of stack memory this code consumes when SIZE = 43690. AFAIK, vectors use 24B stack memory, so the total comes to 24B * 43690 = 1048560B. This number is very close to 220 = 1048576. In fact, SIZE = 43691 is the first time that the consumed stack memory exceeds 220B. Unless this is quite some coincidence, my stack memory is somehow limited to 220B = 2M. If that really is the case, I still cannot find any way to increase it via the compilation command arguments. All the solutions in the internet leads to the stack_size linker argument, but it doesn't seem to work on my machine. I'm wondering now if it's because of the M1 chip somehow.
I'm aware that I can change this code to use vector of vectors to consume memory from the heap, but I have to deal with other's codes very often who are used to coding like this.
Let me know if I need to provide any more details. I've been stuck with this the whole day. Any help would be extremely appreciated. Thanks in advance!
I had the same issue, and after adding the -O2 flag to the compilation command, it started working. No idea why.
So, something like this:
g++-12 -O2 -std=c++17 code.cpp -o code
It does seem to be an M1 / M1 Pro issue. I tested your code on two seperate M1 Pro machine with the same result as yours. One workaround I found is to use the x86_64 version of gcc under rosetta, which doesn't have these allocation problems.
Works on a M1 Max running Monterey 12.5.1 with XCode 13.4.1 and using clang 13.1.6 compiler:
% cat code.cpp
#include <vector>
const int SIZE = 43691;
std::vector<int> v[SIZE];
int main() {
return 0;
}
% cc -std=c++17 code.cpp -o code -lc++
% ./code
Also fails with gcc-12.2.0:
% g++-12 -std=c++17 code.cpp -o code
/var/tmp/ccEnyMCk.s:449:29: error: unexpected token in '.section' directive
.section .data.rel.ro.local
^
So it seems to be a gcc issue on M1 issue.
This is a gcc-12 problem on Darwin Aarch64 targets. It shall not emit such sections like .section .data.rel.ro.local. Section names on macOS shall start with __, eg.: .section __DATA,...
See Mach-O reference.
What is the proper way to load a set of pre-generated LLVM IR and make it available to runtime JIT modules such that the same types aren't given new names and inlining and const propagation can still take place?
My attempt so far:
I compile those C functions to LLVM IR offline via clang -c -emit-llvm -S -ffast-math -msse2 -O3 -o MyLib.ll MyLib.c
For each runtime JIT module, I load the generated LLVM IR via llvm::parseIRFile() and "paste" it into the runtime JIT module via llvm::Linker::linkModules().
This works fine for the first JIT module, but not for subsequent JIT modules created. Each time llvm::parseIRFile() is called, the resulting module's type definitions in the IR is given new names.
For example, offline MyLib.ll looks like this:
%struct.A = type { <4 x float> }
define <4 x float> #Foo(A*)(%struct.A* nocapture readonly)
{
...
}
The resulting module from the first call to llvm::parseIRFile() looks exactly as the offline version. The resulting module from the second call to llvm:parseIRFile() instead looks like:
%struct.A.1 = type { <4 x float> }
define <4 x float> #Foo(A*)(%struct.A.1* nocapture readonly)
{
...
}
Note that %struct.A was renamed to %struct.A.1. The runtime JIT module continues to generate code using %struct.A thus fails to call Foo() since it takes %struct.A.1 instead.
I am trying to compile a CUDA code with following inline assembly:
static __device__ uint get_smid(void) {
uint ret;
asm("mov.u32 %0, %smid;" : "=r"(ret) );
return ret;
}
The code compiles fine with nvcc with a flag -Xptxas -v.
When i try to compile it with clang++ (version 4.0), with corresponding flag -Xcuda-ptxas -v (I think this is right, but I maybe mistaken), I get following error:
../../include/cutil_subset.h:23:25: error: invalid % escape in inline assembly string
asm("mov.u32 %0, %smid;" : "=r"(ret) );
It points to %smid.
I think I am suppose to link proper library but I have this too: L/cuda/install/lib.
Another possibility is NVPTX asm incompatibility. On this page, it is explained that LLVM has different definitions for all PTX variables (there are some for smid and warpid as well). Now I am lost if the mentioned code has to be separately (not inline) written and compiled as such.
Has anybody dealt with similar issue before? Suggestions are welcomed.
You need to reference the special register with a double percent sign: %%smid.
The %% escape sequence gets converted to a single percent sign during compilation, so that ptxas sees the correct special register name. The double percent sign version also works under nvcc.
nvcc seems to be more forgiving with escape sequences in inline assembler than clang++ is, and leaves unknown escape sequences untouched rather than emitting an error as clang does in this case.
I am attempting to compile a C++ code using gcc/5.3 on Scientific Linux release 6.7. I keep getting the following errors whenever I run my Makefile though:
/tmp/ccjZqIED.s: Assembler messages:
/tmp/ccjZqIED.s:768: Error: no such instruction: `shlx %rax,%rdx,%rdx'
/tmp/ccjZqIED.s:1067: Error: no such instruction: `shlx %rax,%rdx,%rdx'
/tmp/ccjZqIED.s: Assembler messages:
/tmp/ccjZqIED.s:6229: Error: no such instruction: `mulx %r10,%rcx,%rbx'
/tmp/ccjZqIED.s:6248: Error: no such instruction: `mulx %r13,%rcx,%rbx'
/tmp/ccjZqIED.s:7109: Error: no such instruction: `mulx %r10,%rcx,%rbx'
/tmp/ccjZqIED.s:7128: Error: no such instruction: `mulx %r13,%rcx,%rbx'
I've attmpted to follow the advice from this question with no change to my output:
Compile errors with Assembler messages
My compiler options are currently:
CXXFLAGS = -g -Wall -O0 -pg -std=c++11
Does anyone have any idea what could be causing this?
This means that GCC is outputting an instruction that your assembler doesn't support. Either that's coming from inline asm in the source code, or that shouldn't happen, and suggests that you have compiled GCC on a different machine with a newer assembler, then copied it to another machine where it doesn't work properly.
Assuming those instructions aren't used explicitly in an asm statement you should be able to tell GCC not to emit those instructions with a suitable flag such as -mno-avx (or whatever flag is appropriate to disable use of those particular instructions).
#jonathan-wakely's answer is correct in that the assembler, which your compiler invokes, does not understand the assembly code, which your compiler generates.
As to why that happens, there are multiple possibilities:
You installed the newer compiler by hand without also updating your assembler
Your compiler generates 64-bit instructions, but assembler is limited to 32-bit ones for some reason
Disabling AVX (-mno-avx) is unlikely to help, because it is not explicitly requested either -- there is no -march in the quoted CXXFLAGS. If it did help, then you did not show us all of the compiler flags -- it would've been best, if you simply included the entire compiler command-line.
If my suspicion is correct in 1. above, then you should build and/or install the latest binutils package, which will provide as aware of AVX instructions, among other things. You would then need to rebuild the compiler with the --with-as=/path/to/the/updated/as flag passed to configure.
If your Linux installation is 32-bit only (suspicion 2.), then you should not be generating 64-bit binaries at all. It is possible, but not trivial...
Do post the output of uname -a and your entire compiler command-line leading to the above error-messages.
Given the following complete program:
#include <functional>
struct jobbie
{
std::function<void()> a;
};
void do_jobbie(jobbie j = {})
{
if (j.a)
j.a();
}
int main()
{
do_jobbie();
return 0;
}
compiling this on gcc (Ubuntu 4.8.1-2ubuntu1~12.04) 4.8.1:
boom!
richard#DEV1:~/tmp$ g++ -std=c++11 bug.cpp
bug.cpp: In function ‘int main()’:
bug.cpp:16:13: internal compiler error: in create_tmp_var, at gimplify.c:479
do_jobbie();
^
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-4.8/README.Bugs> for instructions.
Preprocessed source stored into /tmp/ccWGpb7M.out file, please attach this to your bugreport.
However, clang [Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)] is happy with it.
$ clang++ -std=c++11 bug.cpp
It seems to me that clang is correctly deducing that j defaults to a default-constructed jobbie object whereas gcc is (obviously) blowing up.
replacing line 8 with void do_jobbie(jobbie j = jobbie {}) fixes the problem on gcc.
Question - which of these is true:
clang is correct, gcc is faulty (ignoring the compiler blow-up)
clang is over-reaching the standard and it should not really compile
the standard does not make it clear?
An internal compiler error is always a compiler bug. Compilers should be able to process anything without crashing like that.
clang has similar handling for when it crashes, producing data for reporting the bug and pointing the user to clang's bug reporting web page.
I don't see anything tricky about this code. It seems straightforward to me that it should compile and run.
This indicates that it should work:
The default argument has the same semantic constraints as the initializer in a declaration of a variable of the parameter type, using the copy-initialization semantics.
(8.3.6, wording from draft n3936)