Skip to content

[LICM] Mul association incorrectly combines no-wrap flags #85457

Closed
@aleks-tmb

Description

@aleks-tmb

After the #67736 LICM turns the following IR

define i32 @test() {
entry:
  br label %loop

loop:
  %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop ]
  %iv.next = add nuw nsw i32 %iv, 1
  %mul0 = mul nuw nsw i32 30000, %iv
  %mul1 = mul nuw i32 %mul0, 30000
  %cmp = icmp slt i32 %mul1, 1
  br i1 %cmp, label %exit, label %loop

exit:
  ret i32 0
}

into the

define i32 @test() {
entry:
  br label %loop

loop:                                             ; preds = %loop, %entry
  %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop ]
  %iv.next = add nuw nsw i32 %iv, 1
  %mul0 = mul nuw nsw i32 900000000, %iv
  %cmp = icmp slt i32 %mul0, 1
  br i1 %cmp, label %exit, label %loop

exit:                                             ; preds = %loop
  ret i32 0
}

https://godbolt.org/z/G5zvEzYEv

The resulting mul instruction has 2 flags nuw nsw, while in the source code it has nuw only. That transformation seems to be incorrect.

If we run instcombine for the case, it would provide mul nuw i32 %iv, 900000000:
https://godbolt.org/z/6oWrPbEMn

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions