Florian Hahn 13ffde316a
[ConstraintElim] Remove dead compares after simplification.
Remove compares after replacing all uses. Cleaning dead compares can
enable additional simplifications when adjusting the position of the
pass slightly. In particular, it seems like the additional dead
instructions may prevent SimplifyCFG performing some folds.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D158760
2023-08-24 22:12:57 +01:00

245 lines
6.2 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
declare void @use(i1)
define void @test_1_variable_constraint(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @test_1_variable_constraint(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]
; CHECK: bb1:
; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[X]], 10
; CHECK-NEXT: call void @use(i1 [[C_2]])
; CHECK-NEXT: [[C_3:%.*]] = icmp ule i8 [[Y]], [[X]]
; CHECK-NEXT: call void @use(i1 [[C_3]])
; CHECK-NEXT: [[C_4:%.*]] = icmp ule i8 10, [[X]]
; CHECK-NEXT: call void @use(i1 [[C_4]])
; CHECK-NEXT: ret void
; CHECK: bb2:
; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: call void @use(i1 false)
; CHECK-NEXT: [[C_5:%.*]] = icmp ule i8 [[X]], 10
; CHECK-NEXT: call void @use(i1 [[C_5]])
; CHECK-NEXT: [[C_6:%.*]] = icmp ule i8 10, [[X]]
; CHECK-NEXT: call void @use(i1 [[C_6]])
; CHECK-NEXT: ret void
;
entry:
%c.1 = icmp ule i8 %x, %y
br i1 %c.1, label %bb1, label %bb2
bb1:
%t.1 = icmp ule i8 %x, %y
call void @use(i1 %t.1)
%c.2 = icmp ule i8 %x, 10
call void @use(i1 %c.2)
%c.3 = icmp ule i8 %y, %x
call void @use(i1 %c.3)
%c.4 = icmp ule i8 10, %x
call void @use(i1 %c.4)
ret void
bb2:
%t.2 = icmp ule i8 %y, %x
call void @use(i1 %t.2)
%f.1 = icmp ule i8 %x, %y
call void @use(i1 %f.1)
%c.5 = icmp ule i8 %x, 10
call void @use(i1 %c.5)
%c.6 = icmp ule i8 10, %x
call void @use(i1 %c.6)
ret void
}
define void @test_1_constant_constraint(i8 %x) {
; CHECK-LABEL: @test_1_constant_constraint(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]]
; CHECK: bb1:
; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[X]], 9
; CHECK-NEXT: call void @use(i1 [[C_2]])
; CHECK-NEXT: [[C_4:%.*]] = icmp ule i8 10, [[X]]
; CHECK-NEXT: call void @use(i1 [[C_4]])
; CHECK-NEXT: ret void
; CHECK: bb2:
; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: call void @use(i1 false)
; CHECK-NEXT: call void @use(i1 false)
; CHECK-NEXT: [[C_5:%.*]] = icmp ule i8 [[X]], 11
; CHECK-NEXT: call void @use(i1 [[C_5]])
; CHECK-NEXT: [[C_6:%.*]] = icmp ule i8 12, [[X]]
; CHECK-NEXT: call void @use(i1 [[C_6]])
; CHECK-NEXT: ret void
;
entry:
%c.1 = icmp ule i8 %x, 10
br i1 %c.1, label %bb1, label %bb2
bb1:
%t.1 = icmp ule i8 %x, 10
call void @use(i1 %t.1)
%t.2 = icmp ule i8 %x, 11
call void @use(i1 %t.2)
%c.2 = icmp ule i8 %x, 9
call void @use(i1 %c.2)
%c.4 = icmp ule i8 10, %x
call void @use(i1 %c.4)
ret void
bb2:
%t.3 = icmp ule i8 10, %x
call void @use(i1 %t.3)
%f.1 = icmp ule i8 %x, 9
call void @use(i1 %f.1)
%f.1.1 = icmp ule i8 %x, 10
call void @use(i1 %f.1.1)
%c.5 = icmp ule i8 %x, 11
call void @use(i1 %c.5)
%c.6 = icmp ule i8 12, %x
call void @use(i1 %c.6)
ret void
}
define i8 @test1(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
; CHECK: bb1:
; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[Y]], [[Z:%.*]]
; CHECK-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]]
; CHECK: bb2:
; CHECK-NEXT: br i1 true, label [[BB3:%.*]], label [[EXIT]]
; CHECK: bb3:
; CHECK-NEXT: ret i8 10
; CHECK: exit:
; CHECK-NEXT: ret i8 20
;
entry:
%c.1 = icmp ule i8 %x, %y
br i1 %c.1, label %bb1, label %exit
bb1:
%c.2 = icmp ule i8 %y, %z
br i1 %c.2, label %bb2, label %exit
bb2:
%c.3 = icmp ule i8 %x, %z
br i1 %c.3, label %bb3, label %exit
bb3:
ret i8 10
exit:
ret i8 20
}
define i8 @test2(i8 %x, i8 %y, i8 %z, i8 %a) {
; CHECK-LABEL: @test2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
; CHECK: bb1:
; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[Y]], [[Z:%.*]]
; CHECK-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]]
; CHECK: bb2:
; CHECK-NEXT: [[C_3:%.*]] = icmp ule i8 [[X]], [[A:%.*]]
; CHECK-NEXT: br i1 [[C_3]], label [[BB3:%.*]], label [[EXIT]]
; CHECK: bb3:
; CHECK-NEXT: ret i8 10
; CHECK: exit:
; CHECK-NEXT: ret i8 20
;
entry:
%c.1 = icmp ule i8 %x, %y
br i1 %c.1, label %bb1, label %exit
bb1:
%c.2 = icmp ule i8 %y, %z
br i1 %c.2, label %bb2, label %exit
bb2:
%c.3 = icmp ule i8 %x, %a
br i1 %c.3, label %bb3, label %exit
bb3:
ret i8 10
exit:
ret i8 20
}
define i8 @test3(i8 %x, i8 %y) {
; CHECK-LABEL: @test3(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X:%.*]], 10
; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
; CHECK: bb1:
; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[Y:%.*]], 20
; CHECK-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]]
; CHECK: bb2:
; CHECK-NEXT: ret i8 10
; CHECK: exit:
; CHECK-NEXT: ret i8 20
;
entry:
%c.1 = icmp ule i8 %x, 10
br i1 %c.1, label %bb1, label %exit
bb1:
%c.2 = icmp ule i8 %y, 20
br i1 %c.2, label %bb2, label %exit
bb2:
ret i8 10
exit:
ret i8 20
}
define i8 @test4(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @test4(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[EXIT:%.*]]
; CHECK: bb1:
; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[Y]], [[Z:%.*]]
; CHECK-NEXT: br i1 [[C_2]], label [[BB2:%.*]], label [[EXIT]]
; CHECK: bb2:
; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: [[U_1:%.*]] = icmp eq i8 [[X]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[U_1]])
; CHECK-NEXT: ret i8 10
; CHECK: exit:
; CHECK-NEXT: ret i8 20
;
entry:
%c.1 = icmp ule i8 %x, %y
br i1 %c.1, label %bb1, label %exit
bb1:
%c.2 = icmp ule i8 %y, %z
br i1 %c.2, label %bb2, label %exit
bb2:
%t.1 = icmp ule i8 %x, %z
call void @use(i1 %t.1)
%u.1 = icmp eq i8 %x, %z
call void @use(i1 %u.1)
ret i8 10
exit:
ret i8 20
}