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

Reply via email to