llvm-project/llvm/test/Transforms/ConstraintElimination/monotonic-pointer-phis-crashes.ll
Florian Hahn 6c25c58a4d
[ConstraintElim] Track and simplify conditions at use.
This patch updates ConstraintElimination to track uses of conditions in
the worklist. This allows simplifying conditions using the context that
holds directly at the condition, instead of where the condition is
defined.

This allows us to catch more cases in practice: there are multiple
code-size changes for CTMark while compile-time remains unchanged:
https://llvm-compile-time-tracker.com/compare.php?from=4b020cca9363bebab4643f89cfa92ab2fcc7976c&to=7a6e84b8f029713c137814cd46eec775d24a54a1&stat=instructions:u

This should help to simplify D151799.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D153660
2023-06-27 17:27:49 +01:00

101 lines
3.0 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
declare i1 @cond()
declare void @clobber()
define void @test_unreachable_latch(ptr %start, ptr %b) {
; CHECK-LABEL: define void @test_unreachable_latch
; CHECK-SAME: (ptr [[START:%.*]], ptr [[B:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
; CHECK: loop.header:
; CHECK-NEXT: [[NODE_1:%.*]] = phi ptr [ [[START]], [[ENTRY:%.*]] ], [ null, [[LOOP_LATCH:%.*]] ]
; CHECK-NEXT: [[C_0:%.*]] = icmp ne ptr [[NODE_1]], null
; CHECK-NEXT: br i1 [[C_0]], label [[THEN:%.*]], label [[EXIT:%.*]]
; CHECK: loop.latch:
; CHECK-NEXT: call void @clobber()
; CHECK-NEXT: br label [[LOOP_HEADER]]
; CHECK: if:
; CHECK-NEXT: [[C_2:%.*]] = icmp ne ptr [[B]], null
; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_0]]
; CHECK-NEXT: br i1 [[AND]], label [[THEN]], label [[EXIT]]
; CHECK: then:
; CHECK-NEXT: call void @clobber()
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop.header
loop.header:
%node.1 = phi ptr [ %start, %entry ], [ null, %loop.latch ]
%c.0 = icmp ne ptr %node.1, null
br i1 %c.0, label %then, label %exit
loop.latch: ; No predecessors!
call void @clobber()
br label %loop.header
if:
%c.2 = icmp ne ptr %b, null
%and = and i1 %c.2, %c.0
br i1 %and, label %then, label %exit
then:
call void @clobber()
br label %exit
exit:
ret void
}
define void @test_cond_multi_use_with_one_use_simplified_before_adding_ne_fact(ptr %start, ptr %b) {
; CHECK-LABEL: define void @test_cond_multi_use_with_one_use_simplified_before_adding_ne_fact
; CHECK-SAME: (ptr [[START:%.*]], ptr [[B:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
; CHECK: loop.header:
; CHECK-NEXT: [[NODE_1:%.*]] = phi ptr [ [[START]], [[ENTRY:%.*]] ], [ null, [[LOOP_LATCH:%.*]] ]
; CHECK-NEXT: [[C_0:%.*]] = icmp ne ptr [[NODE_1]], null
; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_LATCH]], label [[EXIT:%.*]]
; CHECK: loop.latch:
; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
; CHECK-NEXT: br i1 [[C_1]], label [[IF:%.*]], label [[LOOP_HEADER]]
; CHECK: if:
; CHECK-NEXT: [[C_2:%.*]] = icmp ne ptr [[B]], null
; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], true
; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[EXIT]]
; CHECK: then:
; CHECK-NEXT: call void @clobber()
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop.header
loop.header:
%node.1 = phi ptr [ %start, %entry ], [ null, %loop.latch ]
%c.0 = icmp ne ptr %node.1, null
br i1 %c.0, label %loop.latch, label %exit
loop.latch:
%c.1 = call i1 @cond()
br i1 %c.1, label %if, label %loop.header
if:
%c.2 = icmp ne ptr %b, null
%and = and i1 %c.2, %c.0
br i1 %and, label %then, label %exit
then:
call void @clobber()
br label %exit
exit:
ret void
}