13 ms·
GodBolt: Enter C, get Assembly
- beardog 10y agoIs this just a toy or does it have any place at all in real assembly projects? (I don't know assembly besides having tinkered with it a bit) Cool project regardless.
- jdub 10y agoIt's really useful to see what key pieces of code look like in assembly (though easy enough to do locally), and reaaaaaaaallllly useful to see what they look like across compilers and architectures. Instead of finding (or worse, building) a compiler or cross compiler locally and doing all the boring steps to compile properly (harder than it sounds) and disassemble the code, you can just splat some code into this and take a peek. Less about "assembly projects", more about breadth of info available to a developer writing C/C++.
- karyon 10y agoi think the primary purpose is to find out what your compiler will do out of your C/C++ program, to see e.g. what optimizations are performed. but who knows, maybe it's also used for actually writing assembly :)
- pkaye 10y agoWhen I used to develop firmware, I would write up the critical inner loops code there and look at the assembly output and tweak the functions to result in better assembly code. Sometimes you can express things a little differently to get around a weakness of the compiler.
- jahnu 10y agoI use it to check things like copy elision etc in my C++.
- harpocrates 10y agoUseful way to see how different compilers interpret the C standard. Just code up a minimal example and see what assembly they produce.
- flukus 10y agoThat's really cool. Is it actually compiling in the background? Is this a tool you wrote?
- znpy 10y agoIt uses gcc behind. I had a chance to read part of the sources and prepare a patched version with a set of toolchains (m68k, amd64, mips). It's nicely written, it's easy to add toolchains as well as to set default compilation options.
- pvg 10y agoIt is running the specified compilers. The github page has more info on how it works. https://github.com/mattgodbolt/gcc-explorer https://github.com/mattgodbolt/gcc-explorer
- pkaye 10y agoIt is kind of what you get when you run gcc with the -S option.
- DvdGiessen 10y agoThere's a post on his blog about how the entire thing runs a bunch of compilers on EC2: http://xania.org/201609/how-compiler-explorer-runs-on-amazon http://xania.org/201609/how-compiler-explorer-runs-on-amazon
- nowne 10y agoThis is an amazing tool, I use it almost daily. Whenever I want to test an idea, or see what is going on in the assembly, I go straight to godbolt.
- source99 10y agoWhat kind of work do you do?
- chrisseaton 10y agoI also use it at least weekly - working on a Ruby JIT I want to see what assembly code is generated from simple C code and compare that to what I'm getting.
- santaclaus 10y agoI don't know about op, but we use the tool a lot. Currently writing performance critical bits of graphics code.
- tenkeyless 10y agoshellcode engineer
- deleted 10y ago[deleted]
- Annatar 10y agoShould be "get assembler". Assembly or assembling is the process of using an assembler to assemble assembler code, which is actually mnemonics.
- vertex-four 10y agoIt's definitely also assembly, possibly even as the primary spelling - https://en.wikipedia.org/wiki/Assembly_language https://en.wikipedia.org/wiki/Assembly_language
- Annatar 10y agoNo, that's just lame (and Wikipedia isn't always right). Ask any scene coder and they'll tell you they're coding in assembler, not "assembly".
- imron 10y agoWhy are scene coders more correct than other coders. If Agner Fog has no problem calling it 'assembly'[0], then neither do I. 0: http://agner.org/optimize/ http://agner.org/optimize/
- Annatar 10y agoWhy are scene coders more correct than other coders. Because they've written more applications in assembler than anyone else in the history of computing. Look at Aminet, and csdb.dk, and that's just Amiga and C=64, I haven't even included the Spectrum, Amstrad CPC, Atari ST and PC.
- phpnode 10y ago> Because they've written more applications in assembler than anyone else in the history of computing. Absolute unbridled nonsense.
- unwind 10y ago
- smitherfield 10y agoI like the highlighting – I finally understand why people say compilers generate faster code than a human could write. Pasted in a pretty straightforward and already fairly optimized function I'd written and of course got back something also pretty straightforward, then I put in "-Ofast -march=native" and, wow. Completely rearranged everything in a totally non-linear way and generated all sorts of bizarre (to me) instructions. I think I'd need to study it for months if not years to understand what the compiler did.
- MichaelBurge 10y agoIf you've never done it before, try stepping through a Haskell program compiled with a recent GHC. The control flow is pretty weird.
- astrange 10y agoYou can follow ghc's compilation with '-v5'. Alas, I've never liked the way it compiles - full of unpredictable jumps, makes no sense at asm level, and just doesn't look a good modern CPU citizen. Of course I am only a minor Haskell learner but jhc could do whole-program compilation with readable assembly. As for gcc, try 'gcc -fdump-tree-all -fdump-rtl-all-slim' and read the 50 files it prints.
- AstralStorm 10y agoOn the other hand, try -Os as in size optimization. You will get readable code that is not slow. I think most people internally optimise readability and thus size, those who don't generally make unmaintainable mush.
- dom0 10y agoDo realize that no Linux distribution ships such binaries. They do the equivalent of -march=$worstSupportedProcessor (eg x86_64). To actually get any benefits from the smart compiler on these you'll need to use FMV and proprietary compiler extensions (eg. GCC per function options), write runtime dispatch code etc. (GCC also has proprietary extensions for that).
- deleted 10y ago[deleted]
- geofft 10y agoNote that "GodBolt" isn't some clever Zeus-inspired service name, "Godbolt" is just this fellow's last name.
- AndrewOMartin 10y agoBut the guy fellow himself may have some divine inspiration, as his work is often next to godliness.
- it 10y agoThere's a Go version too: https://go.godbolt.org https://go.godbolt.org.
- 0x4a42 10y agoAnd a Rust version : https://rust.godbolt.org/ https://rust.godbolt.org/
- asymmetric 10y agoYes, and the title is actually wrong, GodBolt is the last name of the creator, not the project's name (which I believe is Compiler Explorer)
- rzimmerman 10y agoTry with gcc 6.2 options -Ofast -march=native: int square(int num) { int a = 0; for (int x = 0; x < num; x+=2) { if (!(x % 2)) { a += x; } } return a; } All kinds of loop unrolling and vector instructions. Now remove the "!"
- OskarS 10y agoDude, modern compilers are smart.
- user51442 10y agoA simple recursive factorial function: https://godbolt.org/g/97dUFg https://godbolt.org/g/97dUFg Not sure if that's smart or stupid.
- deleted 10y ago[deleted]
- GlitchMr 10y agoIt does try to vectorize it (doing multiple math operations at once is faster). (1 * 5 * 9 * 13 * 17 * ...) * (2 * 6 * 10 * 14 * 18 * ...) * (3 * 7 * 11 * 15 * 19 * ...) * (4 * 8 * 12 * 16 * 20 * ...) (it's not precisely that, but close enough) It isn't optimal however, optimal code would be pre-computed results (signed integer overflow is undefined, so n <= 12 is defined) (if signed integer overflow would be defined to be 2's complement overflow, you can still use a table, as n > 33 gives 0)
- Tuna-Fish 10y agoDude, your code got: 1. Turned from recursive form into iterative form 2. Unrolled heavily 3. Autovectorized (!) The throughput will be substantially more than the simple version.
- user51442 10y agoWell, the optimizations are pretty smart to be sure, the stupid thing is that anything over 12! overflows (as GlitchMr points out). I'd like to know how the recursion to iteration step was done.
- jdub 10y agoCool! Certainly quicker than loading up cross compilers (even when they're so easy to get on Debian/Ubuntu), building a binary, and running the right version of objdump. The Rust Playground at https://play.rust-lang.org/ https://play.rust-lang.org/ has a similar function, letting you check ASM, LLVM IR, and MIR (Rust's mid-level intermediate representation) output for current versions of the Rust compiler.
- masklinn 10y agoFWIW godbolt also does rust (http://rust.godbolt.org http://rust.godbolt.org) which is convenient because play.rust-lang.org doesn't perform the aggressive cleanup/removal of assembly godbolt does.
- kibwen 10y agoThough it looks like godbolt only has a Rust compiler up to version 1.11 (current stable is 1.13), so it may not be including optimizations in the current Rust release.
- steveklabnik 10y agohttps://github.com/mattgodbolt/gcc-explorer/issues/139 https://github.com/mattgodbolt/gcc-explorer/issues/139
- jerven 10y agoReally cool, it surprised me to see even trivial code give very different results in gcc,icc and clang. int retNum(int num, int num2) { return (num * num2)/num; } gives this in clang retNum(int, int): # @retNum(int, int) mov eax, esi ret While icc and gcc give retNum(int, int): mov eax, esi imul eax, edi cdq idiv edi ret retNum(int, int): imul esi, edi mov eax, esi cdq idiv edi ret The clang version at first sight seem right. But then thinking about it this is integer math. 4/3 := 1 1 * 3 := 3 leads to 3 != 4 I believe gcc and icc returning 3 there is correct, while clang returning 4 is not. Maybe someone more C/int versed can tell us which are acceptable (knowing C both might be ok)
- comex 10y agoThe product of 'num' and 'num2' is always going to be a multiple of 'num', so there won't be any error introduced by flooring when dividing by 'num' again. One thing that can happen is an integer overflow: if you pass (0x10000, 0x10000), icc's and gcc's versions will calculate 0x10000 * 0x10000 = 0, 0 / 0x10000 = 0, while clang will return 0x10000. But clang's not wrong: signed integer overflow is undefined behavior in C, so compilers are allowed to just assume it never happens when making optimizations.
- AstralStorm 10y agoThere is a flag that enables such optimization behaviour for GCC. I think it is part of Ofast. If it does not work in new GCC it is a bug.
- chrisseaton 10y ago(num * num2)/num = num2 The division cancels out the multiplication. Just like if you were doing arithmetic on paper as you did in school. There's nothing more to it than that is there? What inputs do you think it's incorrect for in clang? Overflow is of course undefined.
- syphilis2 10y agoI can't edit the code samples using a mobile Firefox browser. Attempting to delete text and then type new text results in the deleted text reappearing appended to whatever new text I typed.
- mattgodbolt 10y agoSadly the mobile support is pretty bad. It's on my list to fix at some point but requires a bunch of changes in the underlying window library (golden-layout.com), plus some work to reconfigure the layout for mobile.
- poseid 10y agoreally nice project - i was playing with compilers and javascript a while ago see http://embeddednodejs.com/compiler http://embeddednodejs.com/compiler - as a simple experiment to learn about javascript's role in compilers
- JoshTriplett 10y agoOne optimization I've always found impressive: #include <stdint.h> uint32_t testFunction(uint32_t x) { return ((x & 0xff) << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | ((x & 0xff000000) >> 24); } compiles into: testFunction(unsigned int): mov eax, edi bswap eax ret Another fun one, that only works with clang: #include <stdint.h> int testFunction(uint64_t x) { int count; for (count = 0; x; count++) x &= x - 1; return count; } compiles into: testFunction(unsigned long): popcnt rax, rdi ret
- eridius 10y agoImpressive? Those are probably specially-coded optimizations rather than the result of generic optimizations.
- JoshTriplett 10y agoAs I understand it, the bswap optimization doesn't pattern-match for that specific code (and it works for any equivalent shift/mask code); it analyzes the flow of the bits to figure out the final bit pattern relative to the original, realizes the whole expression had the effect of a bswap, and substitutes a bswap.
- dom0 10y agoYes, that's called pattern matching.
- IshKebab 10y agoNot the kind of pattern matching they were talking about.
- sunfish 10y agoActually, in LLVM's case it really is just explicitly checking for a few specific bswap patterns rather than doing anything fancy: https://github.com/llvm-mirror/llvm/blob/master/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp#L1594 https://github.com/llvm-mirror/llvm/blob/master/lib/Transfor...
- pjmlp 10y agoFor D, https://d.godbolt.org/ https://d.godbolt.org/ Also this is actually a repost from one year ago, https://news.ycombinator.com/item?id=11671730 https://news.ycombinator.com/item?id=11671730
- suprjami 10y agoWas gonna say, pretty sure I know about this site because of HN.
- rado 10y agoReminds me of SPHINX C--, which was great.
- xroche 10y agoThis site is extremely valuable to produce good quality reports of GCC bugs. For https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67283 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67283, I was able to track multiple regressions on a GCC optimization over the different versions of GCC, within few minutes. Doing the same manually would have been extremely tiresome. Kudos to the website authors!
- jawilson2 10y agoWe use this all the time at work. Also, Matt Godbolt sits about 3 rows away from me, which helps as well!
- rawnlq 10y agoXcode has a disassembly view that's really similar (and works with lldb!). After moving back to linux I haven't found a replacement ide that's as nice for doing c++ development.
- AstralStorm 10y agoPity it isn't a recompiler.
- selckin 10y agoJava version @ https://javap.yawk.at/ https://javap.yawk.at/
- the8472 10y agothat's just generated bytecode, not the assembly output on a particular platform generated by the optimizing JIT. Most of the optimizing magic happens in the JITs, not javac.
- deleted 10y ago[deleted]
- samlittlewood 10y agoAlso, look at Matt's write up of how this works: http://xania.org/201609/how-compiler-explorer-runs-on-amazon http://xania.org/201609/how-compiler-explorer-runs-on-amazon as a pragmatic example (incl. all tools & configs) of how to build an auto scaling & deploying site, without overdosing on kool-aid.
- teddyuk 10y agowe need a DevilBolt: Enter Assembly, get C!
- wibr 10y agoI know C but no Assembler, so this looks like a good way to get more familiar with what's going on under the hood. It would be really neat if you could click on each instruction/register to get a short summary, though.
- rocky1138 10y agoThis is such a good suggestion. I'd love to see Motorola 68000 support.
- deleted 10y ago[deleted]
- zitterbewegung 10y agoI put in Duff's Device looked interesting. https://godbolt.org/g/SVhqKP https://godbolt.org/g/SVhqKP https://en.wikipedia.org/wiki/Duff's_device https://en.wikipedia.org/wiki/Duff's_device
- cfv 10y agoCan anyone please explain why this naive pow() implementation is so freaking huge? I lack the chops to figure this out properly https://godbolt.org/g/YFvNWa https://godbolt.org/g/YFvNWa
- jcranmer 10y agoThe loop was unrolled with a large factor. The loop was also vectorized, so that each multiply is a 4-element vector multiplication, with the final result being a horizontal reduction. The rest of the mess is trying to account for all of the cases where the input power is not a multiple of 128.
- ndesaulniers 10y agofolks interested in doing this locally should play around with objdump
- anthk 10y agosquare(int): mul r0, r0, r0 bx lr Mips is damn awesome.
- cptank420 10y agoC
- Roboprog 10y agoCool. I missed the target option list on the right the first time I looked at the page. The closest I've ever come to this back in the day was running (Borland) Turbo Debugger's assembly view after building with Turbo C (w/ or w/out -O...), as either 8086 or 80286 output - "x16". Yeah, that was a while back :-)
- nwmcsween 10y agoWhat would be incredibly useful is if I could do this within vim doing side-by-side split.
- finbar 10y agoAwesome project. And Just in time for an assembly-intensive computer organization final