Nikita Popov 75881dbb0f
[JumpThreading] Don't phi translate past loop phi (#70664)
When evaluating comparisons in predecessors, phi operands are translated
into the predecessor. If the translation is across a backedge, this
means that the two operands of the icmp will be from two different loop
iterations, resulting in incorrect simplification.

Fix this by not performing the phi translation for phis in loop headers.

Note: This is not a complete fix. If the
jump-threading-across-loop-headers option is enabled, the LoopHeaders
variable does not get populated. Additional changes will be needed to
fix that case.

Related to https://github.com/llvm/llvm-project/issues/70651.
2023-10-31 10:20:07 +01:00

48 lines
1.9 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
; RUN: opt -S -passes=jump-threading < %s | FileCheck %s
; RUN: opt -S -passes=jump-threading -jump-threading-across-loop-headers < %s | FileCheck %s --check-prefix=THREAD-LOOP
; FIXME: This is a miscompile if -jump-threading-across-loop-headers is enabled.
define i64 @test(i64 %v) {
; CHECK-LABEL: define i64 @test(
; CHECK-SAME: i64 [[V:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[V_NONNEG:%.*]] = icmp sgt i64 [[V]], -1
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[SUM:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[SUM_NEXT:%.*]], [[FOR_BODY]] ]
; CHECK-NEXT: [[SUM_NEXT]] = add i64 [[SUM]], [[V]]
; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ult i64 [[SUM_NEXT]], [[SUM]]
; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[V_NONNEG]], [[OVERFLOW]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret i64 [[SUM]]
;
; THREAD-LOOP-LABEL: define i64 @test(
; THREAD-LOOP-SAME: i64 [[V:%.*]]) {
; THREAD-LOOP-NEXT: entry:
; THREAD-LOOP-NEXT: [[V_NONNEG:%.*]] = icmp sgt i64 [[V]], -1
; THREAD-LOOP-NEXT: br label [[FOR_BODY:%.*]]
; THREAD-LOOP: for.body:
; THREAD-LOOP-NEXT: [[SUM:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[SUM_NEXT:%.*]], [[FOR_BODY]] ]
; THREAD-LOOP-NEXT: [[SUM_NEXT]] = add i64 [[SUM]], [[V]]
; THREAD-LOOP-NEXT: [[OVERFLOW:%.*]] = icmp ult i64 [[SUM_NEXT]], [[SUM]]
; THREAD-LOOP-NEXT: br i1 [[V_NONNEG]], label [[FOR_BODY]], label [[EXIT:%.*]]
; THREAD-LOOP: exit:
; THREAD-LOOP-NEXT: ret i64 [[SUM]]
;
entry:
%v.nonneg = icmp sgt i64 %v, -1
br label %for.body
for.body:
%sum = phi i64 [ 0, %entry ], [ %sum.next, %for.body ]
%sum.next = add i64 %sum, %v
%overflow = icmp ult i64 %sum.next, %sum
%cmp = xor i1 %v.nonneg, %overflow
br i1 %cmp, label %for.body, label %exit
exit:
ret i64 %sum
}