[ConstraintElimination] Add test cases with @llvm.assume.
This commit is contained in:
parent
8e9808ca3a
commit
097925aab9
|
|
@ -0,0 +1,272 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -constraint-elimination -S %s | FileCheck %s
|
||||
|
||||
declare void @llvm.assume(i1)
|
||||
|
||||
declare void @may_unwind()
|
||||
|
||||
declare void @use(i1)
|
||||
|
||||
define i1 @assume_dominates(i8 %a, i8 %b, i1 %c) {
|
||||
; CHECK-LABEL: @assume_dominates(
|
||||
; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
|
||||
; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
|
||||
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
|
||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
||||
; CHECK: then:
|
||||
; CHECK-NEXT: [[T_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
|
||||
; CHECK-NEXT: [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
|
||||
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[T_1]], [[T_2]]
|
||||
; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
|
||||
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
|
||||
; CHECK-NEXT: ret i1 [[RES_2]]
|
||||
; CHECK: else:
|
||||
; CHECK-NEXT: [[T_3:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
|
||||
; CHECK-NEXT: [[T_4:%.*]] = icmp ule i8 [[A]], [[B]]
|
||||
; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[T_3]], [[T_4]]
|
||||
; CHECK-NEXT: [[ADD_2_1:%.*]] = add nuw nsw i8 [[A]], 2
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[ADD_2_1]], [[B]]
|
||||
; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_2]]
|
||||
; CHECK-NEXT: ret i1 [[RES_4]]
|
||||
;
|
||||
%add.1 = add nsw nuw i8 %a, 1
|
||||
%cmp.1 = icmp ule i8 %add.1, %b
|
||||
call void @llvm.assume(i1 %cmp.1)
|
||||
br i1 %c, label %then, label %else
|
||||
|
||||
then:
|
||||
%t.1 = icmp ule i8 %add.1, %b
|
||||
%t.2 = icmp ule i8 %a, %b
|
||||
%res.1 = xor i1 %t.1, %t.2
|
||||
%add.2 = add nsw nuw i8 %a, 2
|
||||
%c.1 = icmp ule i8 %add.2, %b
|
||||
%res.2 = xor i1 %res.1, %c.1
|
||||
ret i1 %res.2
|
||||
|
||||
else:
|
||||
%t.3 = icmp ule i8 %add.1, %b
|
||||
%t.4 = icmp ule i8 %a, %b
|
||||
%res.3 = xor i1 %t.3, %t.4
|
||||
%add.2.1 = add nsw nuw i8 %a, 2
|
||||
%c.2 = icmp ule i8 %add.2.1, %b
|
||||
%res.4 = xor i1 %res.3, %c.2
|
||||
ret i1 %res.4
|
||||
}
|
||||
|
||||
define i1 @assume_same_bb(i8 %a, i8 %b, i1 %c) {
|
||||
; CHECK-LABEL: @assume_same_bb(
|
||||
; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
|
||||
; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
|
||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
||||
; CHECK: then:
|
||||
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
|
||||
; CHECK-NEXT: [[T_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
|
||||
; CHECK-NEXT: [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
|
||||
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[T_1]], [[T_2]]
|
||||
; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
|
||||
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
|
||||
; CHECK-NEXT: ret i1 [[RES_2]]
|
||||
; CHECK: else:
|
||||
; CHECK-NEXT: [[T_3:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
|
||||
; CHECK-NEXT: [[T_4:%.*]] = icmp ule i8 [[A]], [[B]]
|
||||
; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[T_3]], [[T_4]]
|
||||
; CHECK-NEXT: [[ADD_2_1:%.*]] = add nuw nsw i8 [[A]], 2
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[ADD_2_1]], [[B]]
|
||||
; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_2]]
|
||||
; CHECK-NEXT: ret i1 [[RES_4]]
|
||||
;
|
||||
%add.1 = add nsw nuw i8 %a, 1
|
||||
%cmp.1 = icmp ule i8 %add.1, %b
|
||||
br i1 %c, label %then, label %else
|
||||
|
||||
then:
|
||||
call void @llvm.assume(i1 %cmp.1)
|
||||
%t.1 = icmp ule i8 %add.1, %b
|
||||
%t.2 = icmp ule i8 %a, %b
|
||||
%res.1 = xor i1 %t.1, %t.2
|
||||
%add.2 = add nsw nuw i8 %a, 2
|
||||
%c.1 = icmp ule i8 %add.2, %b
|
||||
%res.2 = xor i1 %res.1, %c.1
|
||||
ret i1 %res.2
|
||||
|
||||
else:
|
||||
%t.3 = icmp ule i8 %add.1, %b
|
||||
%t.4 = icmp ule i8 %a, %b
|
||||
%res.3 = xor i1 %t.3, %t.4
|
||||
%add.2.1 = add nsw nuw i8 %a, 2
|
||||
%c.2 = icmp ule i8 %add.2.1, %b
|
||||
%res.4 = xor i1 %res.3, %c.2
|
||||
ret i1 %res.4
|
||||
}
|
||||
|
||||
|
||||
define i1 @assume_same_bb2(i8 %a, i8 %b, i1 %c) {
|
||||
; CHECK-LABEL: @assume_same_bb2(
|
||||
; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
|
||||
; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
|
||||
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
|
||||
; CHECK-NEXT: [[T_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
|
||||
; CHECK-NEXT: [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
|
||||
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[T_1]], [[T_2]]
|
||||
; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
|
||||
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
|
||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: ret i1 [[RES_2]]
|
||||
;
|
||||
%add.1 = add nsw nuw i8 %a, 1
|
||||
%cmp.1 = icmp ule i8 %add.1, %b
|
||||
call void @llvm.assume(i1 %cmp.1)
|
||||
%t.1 = icmp ule i8 %add.1, %b
|
||||
%t.2 = icmp ule i8 %a, %b
|
||||
%res.1 = xor i1 %t.1, %t.2
|
||||
%add.2 = add nsw nuw i8 %a, 2
|
||||
%c.1 = icmp ule i8 %add.2, %b
|
||||
%res.2 = xor i1 %res.1, %c.1
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret i1 %res.2
|
||||
}
|
||||
|
||||
|
||||
; TODO: Keep track of position of assume and may unwinding calls, simplify
|
||||
; conditions if possible.
|
||||
define i1 @assume_same_bb_after_may_exiting_call(i8 %a, i8 %b, i1 %c) {
|
||||
; CHECK-LABEL: @assume_same_bb_after_may_exiting_call(
|
||||
; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
|
||||
; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
|
||||
; CHECK-NEXT: call void @may_unwind()
|
||||
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
|
||||
; CHECK-NEXT: [[T_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
|
||||
; CHECK-NEXT: [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
|
||||
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[T_1]], [[T_2]]
|
||||
; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
|
||||
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
|
||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: ret i1 [[RES_2]]
|
||||
;
|
||||
%add.1 = add nsw nuw i8 %a, 1
|
||||
%cmp.1 = icmp ule i8 %add.1, %b
|
||||
call void @may_unwind()
|
||||
call void @llvm.assume(i1 %cmp.1)
|
||||
%t.1 = icmp ule i8 %add.1, %b
|
||||
%t.2 = icmp ule i8 %a, %b
|
||||
%res.1 = xor i1 %t.1, %t.2
|
||||
%add.2 = add nsw nuw i8 %a, 2
|
||||
%c.1 = icmp ule i8 %add.2, %b
|
||||
%res.2 = xor i1 %res.1, %c.1
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret i1 %res.2
|
||||
}
|
||||
|
||||
; TODO: Keep track of position of assume and may unwinding calls, simplify
|
||||
; conditions if possible.
|
||||
define i1 @assume_same_bb_before_may_exiting_call(i8 %a, i8 %b, i1 %c) {
|
||||
; CHECK-LABEL: @assume_same_bb_before_may_exiting_call(
|
||||
; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
|
||||
; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
|
||||
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
|
||||
; CHECK-NEXT: call void @may_unwind()
|
||||
; CHECK-NEXT: [[T_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
|
||||
; CHECK-NEXT: [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
|
||||
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[T_1]], [[T_2]]
|
||||
; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
|
||||
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
|
||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: ret i1 [[RES_2]]
|
||||
;
|
||||
%add.1 = add nsw nuw i8 %a, 1
|
||||
%cmp.1 = icmp ule i8 %add.1, %b
|
||||
call void @llvm.assume(i1 %cmp.1)
|
||||
call void @may_unwind()
|
||||
%t.1 = icmp ule i8 %add.1, %b
|
||||
%t.2 = icmp ule i8 %a, %b
|
||||
%res.1 = xor i1 %t.1, %t.2
|
||||
%add.2 = add nsw nuw i8 %a, 2
|
||||
%c.1 = icmp ule i8 %add.2, %b
|
||||
%res.2 = xor i1 %res.1, %c.1
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret i1 %res.2
|
||||
}
|
||||
|
||||
define i1 @assume_same_bb_after_condition(i8 %a, i8 %b, i1 %c) {
|
||||
; CHECK-LABEL: @assume_same_bb_after_condition(
|
||||
; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
|
||||
; CHECK-NEXT: [[T_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
|
||||
; CHECK-NEXT: [[T_2:%.*]] = icmp ule i8 [[A]], [[B]]
|
||||
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[T_1]], [[T_2]]
|
||||
; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
|
||||
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_1]]
|
||||
; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
|
||||
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
|
||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: ret i1 [[RES_2]]
|
||||
;
|
||||
%add.1 = add nsw nuw i8 %a, 1
|
||||
%t.1 = icmp ule i8 %add.1, %b
|
||||
%t.2 = icmp ule i8 %a, %b
|
||||
%res.1 = xor i1 %t.1, %t.2
|
||||
%add.2 = add nsw nuw i8 %a, 2
|
||||
%c.1 = icmp ule i8 %add.2, %b
|
||||
%res.2 = xor i1 %res.1, %c.1
|
||||
%cmp.1 = icmp ule i8 %add.1, %b
|
||||
call void @llvm.assume(i1 %cmp.1)
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret i1 %res.2
|
||||
}
|
||||
|
||||
; The function may exit before the assume if @may_unwind unwinds. Conditions
|
||||
; before the call cannot be simplified.
|
||||
define i1 @assume_same_bb_after_condition_may_unwind_between(i8 %a, i8 %b, i1 %c) {
|
||||
; CHECK-LABEL: @assume_same_bb_after_condition_may_unwind_between(
|
||||
; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[A:%.*]], 1
|
||||
; CHECK-NEXT: [[C_1:%.*]] = icmp ule i8 [[ADD_1]], [[B:%.*]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_1]])
|
||||
; CHECK-NEXT: [[C_2:%.*]] = icmp ule i8 [[A]], [[B]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_2]])
|
||||
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[C_1]], [[C_2]]
|
||||
; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[A]], 2
|
||||
; CHECK-NEXT: [[C_3:%.*]] = icmp ule i8 [[ADD_2]], [[B]]
|
||||
; CHECK-NEXT: call void @use(i1 [[C_3]])
|
||||
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_3]]
|
||||
; CHECK-NEXT: [[CMP_1:%.*]] = icmp ule i8 [[ADD_1]], [[B]]
|
||||
; CHECK-NEXT: call void @may_unwind()
|
||||
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_1]])
|
||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: ret i1 [[RES_2]]
|
||||
;
|
||||
%add.1 = add nsw nuw i8 %a, 1
|
||||
%c.1 = icmp ule i8 %add.1, %b
|
||||
call void @use(i1 %c.1)
|
||||
%c.2 = icmp ule i8 %a, %b
|
||||
call void @use(i1 %c.2)
|
||||
%res.1 = xor i1 %c.1, %c.2
|
||||
%add.2 = add nsw nuw i8 %a, 2
|
||||
%c.3 = icmp ule i8 %add.2, %b
|
||||
call void @use(i1 %c.3)
|
||||
%res.2 = xor i1 %res.1, %c.3
|
||||
%cmp.1 = icmp ule i8 %add.1, %b
|
||||
call void @may_unwind()
|
||||
call void @llvm.assume(i1 %cmp.1)
|
||||
br label %exit
|
||||
|
||||
exit:
|
||||
ret i1 %res.2
|
||||
}
|
||||
Loading…
Reference in New Issue