Issue |
154022
|
Summary |
Missed optimization with `-fstrict-enums` for by-value parameters.
|
Labels |
new issue
|
Assignees |
|
Reporter |
keinflue
|
In the following C++ code compiled with `-O2 -fstrict-enums`, the second function is optimized to return `false` unconditionally, while the first one isn't:
```cpp
enum E { A, B };
bool f(E e) { return e > 1; };
bool g(E& e) { return e > 1; };
```
```asm
_Z1f1E:
cmp edi, 2
setge al
ret
_Z1gR1E:
xor eax, eax
ret
```
`f` should be optimized to return `false` unconditionally just like `g`.
The value range of `E` is [0,1] in C++ and it seems to me that this range information for the load of `e` is present in both cases coming from the Clang codegen, but is ignored and lost during the SROA pass:
```llvm
define dso_local noundef zeroext i1 @_Z1f1E(i32 noundef %0) {
%2 = alloca i32, align 4, !DIAssignID !23
store i32 %0, ptr %2, align 4, !tbaa !25, !DIAssignID !29
%3 = load i32, ptr %2, align 4, !tbaa !25, !range !31, !noundef !32
%4 = icmp sgt i32 %3, 1
ret i1 %4
}
define dso_local noundef zeroext i1 @_Z1gR1E(ptr noundef nonnull align 4 dereferenceable(4) %0) {
%2 = alloca ptr, align 8, !DIAssignID !41
store ptr %0, ptr %2, align 8, !tbaa !43, !DIAssignID !45
%3 = load ptr, ptr %2, align 8, !tbaa !43, !nonnull !32, !align !47
%4 = load i32, ptr %3, align 4, !tbaa !25, !range !31, !noundef !32
%5 = icmp sgt i32 %4, 1
ret i1 %5
}
;...
!31 = !{i32 0, i32 2}
```
=>
```llvm
define dso_local noundef zeroext i1 @_Z1f1E(i32 noundef %0) {
%2 = icmp sgt i32 %0, 1
ret i1 %2
}
define dso_local noundef zeroext i1 @_Z1gR1E(ptr noundef nonnull align 4 dereferenceable(4) %0) {
%2 = load i32, ptr %0, align 4, !tbaa !34, !range !38, !noundef !39
%3 = icmp sgt i32 %2, 1
ret i1 %3
}
```
https://godbolt.org/z/dz8xczYKP
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs