Issue |
123175
|
Summary |
Mul reassociation in instcombine does not maintain NSW (for example impacting alias analysis negatively when canonicalizing GEP)
|
Labels |
llvm:instcombine
|
Assignees |
|
Reporter |
bjope
|
Consider IR like this (also in godbolt here https://godbolt.org/z/rW8K8zfnc):
```
; RUN: opt -passes='aa-eval,instcombine,aa-eval' -print-all-alias-modref-info ....
target datalayout = "p:16:16:16:16"
define i16 @foo1(i16 %x) {
%a = mul nsw nuw i16 %x, 2
%b = mul nsw nuw i16 %a, 3
ret i16 %b
}
define i16 @foo2(i16 %x) {
%a = mul nsw nuw i16 %x, 3
%b = mul nsw nuw i16 %a, 2
ret i16 %b
}
define ptr @foo3(i16 noundef %x, ptr noundef %p) {
%cmp = icmp sgt i16 %x, 0
call void @llvm.assume(i1 %cmp)
%a = mul nsw nuw i16 %x, 3
%idxprom = sext i16 %a to i64
%b = getelementptr inbounds i16, ptr %p, i64 %idxprom
store i16 2, ptr %b
store i16 1, ptr %p
ret ptr %b
}
```
It seems a bit inconsistent that instcombine for foo1 is able to keep "nsw nuw" on the simplified mul
```
%b = mul nuw nsw i16 %x, 6
```
while for foo2 nsw is dropped
```
%b = mul nuw i16 %x, 6
```
and for foo3 both nuw and nsw is dropped on the mul
```
%b.idx = mul i16 %x, 6
%b = getelementptr inbounds i8, ptr %p, i16 %b.idx
```
The foo3 example also show that dropping "nsw" on the mul may impact alias analysis as it no longer is able to derive NoAlias after instcombine.
I think one problem here is that InstCombinerImpl::SimplifyAssociativeOrCommutative only deal with Add/Sub when using the maintainNoSignedWrap helper.
Here (https://alive2.llvm.org/ce/z/RqG2pz) is an alive2 proof showing that we at least should be able to keep nsw on the second mul when doing "(A mul B) mul C" ==> "A mul (B mul C)", as long as the associated Mul operations are both "nsw nuw":
```
define i8 @src(i8 %a, i8 %b, i8 %c) {
%x = mul nsw nuw i8 %a, %b
%y = mul nsw nuw i8 %x, %c
ret i8 %y
}
define i8 @tgt(i8 %a, i8 %b, i8 %c) {
%x = mul i8 %c, %b
%y = mul nsw nuw i8 %x, %a
ret i8 %y
}
```
Maybe there are more situations when "nsw" can be kept given that (B mul C) simplifies, e.g. when all involved values are known to be non-negative?
PS. When using the reassociate pass instead of instcombine the result is even worse, since it drops both "nuw nsw" even for foo1.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs