llvm / llvm/llvm-project

`~a & ~b & ~c` should not compile to `~(a | b | c)`

Open
#163,516 4 comments 0 reactions 1 assignee Claimed by @VachanVY View on GitHub
llvm:SelectionDAG missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

[Zig Godbolt](https://zig.godbo.lt/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:zig,selection:(endColumn:24,endLineNumber:2,positionColumn:24,positionLineNumber:2,selectionStartColumn:24,selectionStartLineNumber:2,startColumn:24,startLineNumber:2),source:'export+fn+foo(a:+u64,+b:+u64,+c:+u64)+u64+%7B%0A++++return+~a+%26+~b+%26+~c%3B%0A%7D'),l:'5',n:'0',o:'Zig+source+%231',t:'0')),k:50.56813902329435,l:'4',m:100,n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:ztrunk,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:2,lang:zig,libs:!(),options:'-O+ReleaseFast+-target+x86_64-linux+-mcpu%3Dicelake_server+-fomit-frame-pointer',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+zig+trunk+(Editor+%231)',t:'0')),header:(),k:49.43186097670565,l:'4',m:100.00000000000001,n:'0',o:'',s:0,t:'0')),l:'2',m:100,n:'0',o:'',t:'0')),version:4)
[C Godbolt](https://c.godbo.lt/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:___c,selection:(endColumn:25,endLineNumber:4,positionColumn:25,positionLineNumber:4,selectionStartColumn:25,selectionStartLineNumber:4,startColumn:25,startLineNumber:4),source:'%23include+%3Cstdint.h%3E%0A%0Auint64_t+foo(uint64_t+a,+uint64_t+b,+uint64_t+c)+%7B%0A++++return+~a+%26+~b+%26+~c%3B%0A%7D%0A'),l:'5',n:'0',o:'C+source+%231',t:'0')),k:50,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((g:!((h:compiler,i:(compiler:cclang_trunk,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:2,lang:___c,libs:!(),options:'-O3+-march%3Dznver5',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+x86-64+clang+(trunk)+(Editor+%231)',t:'0')),header:(),k:50,l:'4',m:53.153209967747166,n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:cgsnapshot,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:___c,libs:!(),options:'-O3+-march%3Dznver5',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+x86-64+gcc+(trunk)+(Editor+%231)',t:'0')),header:(),l:'4',m:46.84679003225283,n:'0',o:'',s:0,t:'0')),k:50,l:'3',n:'0',o:'',t:'0')),l:'2',m:100,n:'0',o:'',t:'0')),version:4)

Currently compiles to:

```asm
foo:
mov rax, rdi
or rax, rsi
or rax, rdx
not rax
ret
```

Should be:

```asm
foo:
not rdx
or rdi, rsi
andn rax, rdi, rdx
ret
```

The difference is that the first snippet is going to take 3 cycles to execute because there is a serial dependency chain between all 3 operations. The second snippet can take 2 cycles to execute because the `not` and the `or` can run in the same cycle.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.