Serguei Katkov 99da317331 [LoopPredication] Fix the LoopPredication by feezing the result of predication.
LoopPredication introduces the use of possibly posion value in branch (guard)
instruction, so to avoid introducing undefined behavior it should be frozen.

Reviewed By: mkazantsev
Differential Revision: https://reviews.llvm.org/D146685
2023-03-29 15:12:00 +07:00

68 lines
2.6 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -passes=loop-predication < %s 2>&1 | FileCheck %s
declare void @llvm.experimental.deoptimize.isVoid(...)
define void @test_01(i1 %cond) {
; CHECK-LABEL: @test_01(
; CHECK-NEXT: bb:
; CHECK-NEXT: [[INST:%.*]] = call i1 @llvm.experimental.widenable.condition()
; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 true
; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], [[INST]]
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: unreached:
; CHECK-NEXT: unreachable
; CHECK: loop:
; CHECK-NEXT: [[INST3:%.*]] = phi i32 [ 0, [[BB:%.*]] ], [ [[INST4:%.*]], [[BACKEDGE:%.*]] ]
; CHECK-NEXT: [[INST4]] = add nsw i32 [[INST3]], 1
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BACKEDGE]], label [[GUARD_BLOCK:%.*]]
; CHECK: normal_ret:
; CHECK-NEXT: ret void
; CHECK: backedge:
; CHECK-NEXT: [[ASSUME_COND:%.*]] = phi i1 [ [[INST9:%.*]], [[GUARD_BLOCK]] ], [ true, [[LOOP]] ]
; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME_COND]])
; CHECK-NEXT: [[INST7:%.*]] = icmp sgt i32 [[INST3]], 137
; CHECK-NEXT: br i1 [[INST7]], label [[UNREACHED:%.*]], label [[LOOP]]
; CHECK: guard_block:
; CHECK-NEXT: [[INST9]] = icmp ult i32 [[INST4]], 10000
; CHECK-NEXT: br i1 [[TMP1]], label [[BACKEDGE]], label [[DEOPT:%.*]]
; CHECK: deopt:
; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid(i32 13) [ "deopt"() ]
; CHECK-NEXT: ret void
; CHECK: done:
; CHECK-NEXT: ret void
;
bb:
%inst = call i1 @llvm.experimental.widenable.condition()
br label %loop
unreached: ; preds = %backedge
unreachable
loop: ; preds = %backedge, %bb
%inst3 = phi i32 [ 0, %bb ], [ %inst4, %backedge ]
%inst4 = add nsw i32 %inst3, 1
br i1 %cond, label %backedge, label %guard_block
normal_ret: ; preds = %loop
ret void
backedge: ; preds = %guard_block, %loop
%inst7 = icmp sgt i32 %inst3, 137
br i1 %inst7, label %unreached, label %loop
guard_block: ; preds = %loop, %loop
%inst9 = icmp ult i32 %inst4, 10000
%inst10 = and i1 %inst9, %inst
br i1 %inst10, label %backedge, label %deopt
deopt: ; preds = %guard_block
call void (...) @llvm.experimental.deoptimize.isVoid(i32 13) [ "deopt"() ]
ret void
done: ; preds = %loop
ret void
}
declare i1 @llvm.experimental.widenable.condition()