logoalt Hacker News

When Compilers Surprise You

224 pointsby brewmarcheyesterday at 1:27 PM95 commentsview on HN

Comments

WalterBrightyesterday at 8:14 PM

These sorts of things are fun and interesting. Compiler optimizations fall into two categories:

1. organized data flow analysis

2. recognizing a pattern and replacing it with a faster version

The first is very effective over a wide range of programs and styles, and is the bulk of the actual transformations. The second is a never-ending accumulation of patterns, where one reaches diminishing returns fairly quickly.

The example in the linked article is very clever and fun, but not really of much value (I've never written a loop like that in 45 years). As mentioned elsewhere "Everyone knows the Gauss Summation formula for sum of n integers i.e. n(n+1)/2" and since everyone knows it why not just write that instead of the loop!

Of course one could say that for any pattern, like replacing i*2 with i<<1, but those pattern replacements are very valuable because they are generated by high level generic coding.

And you could say I'm just being grumpy about this because my optimizer does not do this particular optimization. Fair enough!

show 2 replies
JonChesterfieldyesterday at 3:49 PM

That one is called scalar evolution, llvm abbreviates it as SCEV. The implementation is relatively complicated.

gslinyesterday at 3:49 PM

More similar optimizations: https://matklad.github.io/2025/12/09/do-not-optimize-away.ht...

show 2 replies
vatsachakyesterday at 4:42 PM

Compilers can add way more closed forms. Would it be worth it?

https://en.wikipedia.org/wiki/Wilf%E2%80%93Zeilberger_pair

Validarkyesterday at 9:25 PM

What's actually way cooler about this is that it's generic. Anybody could pattern match the "sum of a finite integer sequence" but the fact that it's general purpose is really awesome.

cjdellyesterday at 11:56 PM

This is really bluring the line between implementation and specification. You may think you're writing the implementation but it is really a proxy for the specification. In other words, the compiler creating an illusion of an imperative machine.

Neywinyyesterday at 6:07 PM

I'm once again surprised at GCC being slower than clang. I would have thought that GCC, which had a 20? year head start would've made faster code. And yet, occasionally I look into the assembly and go "what are you doing?" And the same flags + source into clang is better optimized or uses better instructions or whatever. One time it was bit extraction using shifts. Clang did it in 2 steps: shift left, shift right. GCC did it in 3 I think? I think it maybe shifted right first or maybe did a logical instead of arithmetic and then sign extended. Point is, it was just slower.

show 4 replies
dejjyesterday at 2:53 PM

It’s neat. I wonder if someone attempted detecting a graph coloring problem to replace it with a constant.

show 1 reply
MobiusHorizonsyesterday at 7:32 PM

I will admit I was initially surprised Matt was not already familiar with this behavior given his reputation. I remember discovering it while playing with llvm intermediate representation 10 years ago in college. I would never have considered myself very knowledgeable about modern compilers, and have never done any serious performance work. In that case it had solved a recursion to a simple multiplication, which completely surprised me. The fact that Matt did not know this makes me think this pass may only work on relatively trivial problems that he would never have written in the first place, and therefore never have witnessed the optimization.

show 1 reply
Animatsyesterday at 9:11 PM

That's neat.

A hard problem in optimization today is trying to fit code into the things complex SSE-type instructions can do. Someone recently posted an example where they'd coded a loop to count the number of one bits in a word, and the compiler generated a "popcount" instruction. That's impressive.

show 1 reply
tester756yesterday at 6:12 PM

A lot of hardcoding, making expression consistent, e.g transforming a+3 into 3+a for easier pattern matching

j16sdizyesterday at 5:43 PM

The first thing I had in mind was: the final answer needed to be /2. keeping the number before dividing not overflowing needs some tedious work

show 1 reply
vardumpyesterday at 6:48 PM

Only thing that surprised me was that GCC didn't manage to optimize it. I expected it to be able to do so.

g0wdayesterday at 3:34 PM

If you now have a function where you call this one with an integer literal, you will end up with a fully inlined integer answer!

show 1 reply
andrepdyesterday at 3:15 PM

I'm actually surprised that gcc doesn't do this! If there's one thing compilers do well is pattern match on code patterns and replace with more efficient ones; just try pasting things from Hacker's Delight and watch it always canonicalise it to the equivalent, fastest machine code.

show 2 replies
mgaunardyesterday at 2:39 PM

[flagged]

show 13 replies
maximgeorgeyesterday at 5:06 PM

[flagged]

dist-epochyesterday at 4:05 PM

> I love that despite working with compilers for more than twenty years, they can still surprise and delight me.

This kind of optimization, complete loop removal and computing the final value for simple math loops, is at least 10 years old.

show 2 replies
phplovesongyesterday at 4:01 PM

This exact content was posted a few months ago. Is this AI or just a copy paste job?

show 2 replies