llvm / llvm/llvm-project

LLVM ERROR: Instruction Combining on foo did not reach a fixpoint after 1 iterations.

Open
#222,343 2 comments 0 reactions 0 assignees View on GitHub
llvm:instcombine
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

When looking at some code in visitSelect that analyses users of select instructions to determine if the signedness of zero is insignificant I discovered there is an existing bug for IR like this:

```llvm
declare nofpclass(ninf nnorm nsub nzero nan) float @returns_positive()

; Adapted from ret_always_positive_nonzero__maximum__not_zero_select_positive_or_unknown
; in file Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll

define nofpclass(pinf pnorm psub) float @foo(float %unknown, float nofpclass(zero) %not.zero) {
%always.positive = call float @returns_positive()
%cond = fcmp nnan ogt float %always.positive, %unknown
%select.rhs = select i1 %cond, float %always.positive, float %unknown
%result = call float @llvm.maximum.f32(float %not.zero, float %select.rhs)
ret float %result
}
```

When running this with `opt -S -passes=instcombine < foo.ll` I hit the error:

`LLVM ERROR: Instruction Combining on foo did not reach a fixpoint after 1 iterations. ...`

The problem here is that we add the nsz flag to `call float @llvm.maximum.f32` during the last visit, however when visiting the select during the second iteration we discover the users of the select no longer care about signedness of zero, which triggers an optimisation to fold the fcmp+select into a call to `llvm.maxnum`. It looks like whenever we add the nsz flag to any operation whose input operand may have come from a select we then need to add the select to the worklist.

Contributor guide

Open the contributing guide

Research direction

Start at visitSelect and the InstCombine worklist handling, then reproduce the failure with opt -S -passes=instcombine using the provided IR. Review Transforms/InstCombine/simplify-demanded-fpclass-maximum.ll for related coverage. Done means the reproducer reaches a fixpoint without the LLVM error and regression coverage captures the case.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.