diff options
author | Yingwei Zheng <dtcxzyw2333@gmail.com> | 2024-11-18 17:15:46 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-18 17:15:46 +0800 |
commit | db90673d16e722726aa35fc009cbe6bd0b76b0c0 (patch) | |
tree | 42812949718db502fe900cfec83c712c1906dd69 /llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | |
parent | 6a12b43ac00096976a886bd6d3a1b70a804d09ca (diff) | |
download | llvm-db90673d16e722726aa35fc009cbe6bd0b76b0c0.zip llvm-db90673d16e722726aa35fc009cbe6bd0b76b0c0.tar.gz llvm-db90673d16e722726aa35fc009cbe6bd0b76b0c0.tar.bz2 |
[InstCombine] Re-queue users of phi when nsw/nuw flags of add are inferred (#113933)
This patch re-queue users of phi when one of its incoming add
instructions is updated. If an add instruction is updated, the analysis
results of phis may be improved. Thus we may further fold some users of
this phi node.
See the following case:
```
define i8 @trunc_in_loop_exit_block() {
; CHECK-LABEL: @trunc_in_loop_exit_block(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[IV_NEXT]], [[LOOP_LATCH]] ]
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ult i32 [[IV]], 100
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT:%.*]]
; CHECK: loop.latch:
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
; CHECK-NEXT: br label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[PHI]] to i8
; CHECK-NEXT: ret i8 [[TRUNC]]
;
entry:
br label %loop
loop:
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
%phi = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]
%cmp = icmp ult i32 %iv, 100
br i1 %cmp, label %loop.latch, label %exit
loop.latch:
%iv.next = add i32 %iv, 1
br label %loop
exit:
%trunc = trunc i32 %phi to i8
ret i8 %trunc
}
```
`%iv u< 100` -> infer `nsw/nuw` for `%iv.next = add i32 %iv, 1`
-> `%iv` is non-negative -> infer `samesign` for `%cmp = icmp ult i32
%iv, 100`.
Without re-queuing users of phi nodes, we cannot improve `%cmp` in one
iteration.
Address review comment
https://github.com/llvm/llvm-project/pull/112642#discussion_r1804712271.
This patch also fixes some non-fixpoint issues in tests.
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index fe5e478..a6d6ea5 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1868,6 +1868,15 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) { if (Instruction *Res = foldBinOpOfSelectAndCastOfSelectCondition(I)) return Res; + // Re-enqueue users of the induction variable of add recurrence if we infer + // new nuw/nsw flags. + if (Changed) { + PHINode *PHI; + Value *Start, *Step; + if (matchSimpleRecurrence(&I, PHI, Start, Step)) + Worklist.pushUsersToWorkList(*PHI); + } + return Changed ? &I : nullptr; } |