We should never give up on AAIsDead as it guards other AAs from unreachable code (in which SSA properties are meaningless). We did however use required dependences on some queries in AAIsDead which caused us to invalidate AAIsDead if the queried AA got invalidated. We now use optional dependences instead. The bug that exposed this is added to the liveness.ll test and other test changes show the impact. Bug report by @sdmitriev.
1087 lines
44 KiB
LLVM
1087 lines
44 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
|
|
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=17 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=17 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
|
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
|
|
|
; FIXME: CGSCC is not looking at callees and calleers even though it could be allowed.
|
|
|
|
define i32 @test0(i32* %p) {
|
|
; CHECK-LABEL: define {{[^@]+}}@test0
|
|
; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
|
|
; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[P]], align 4, !range !0
|
|
; CHECK-NEXT: ret i32 [[A]]
|
|
;
|
|
%a = load i32, i32* %p, !range !0
|
|
ret i32 %a
|
|
}
|
|
|
|
define i32 @test0-range-check(i32* %p) {
|
|
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test0-range-check
|
|
; IS__TUNIT_OPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
|
|
; IS__TUNIT_OPM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #3, !range !0
|
|
; IS__TUNIT_OPM-NEXT: ret i32 [[A]]
|
|
;
|
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test0-range-check
|
|
; IS__TUNIT_NPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
|
|
; IS__TUNIT_NPM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #2, !range !0
|
|
; IS__TUNIT_NPM-NEXT: ret i32 [[A]]
|
|
;
|
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test0-range-check
|
|
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
|
|
; IS__CGSCC____-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]])
|
|
; IS__CGSCC____-NEXT: ret i32 [[A]]
|
|
;
|
|
%a = tail call i32 @test0(i32* %p)
|
|
ret i32 %a
|
|
}
|
|
|
|
declare void @use3-dummy(i1, i1, i1)
|
|
define void @use3(i1, i1, i1) {
|
|
; CHECK-LABEL: define {{[^@]+}}@use3
|
|
; CHECK-SAME: (i1 [[TMP0:%.*]], i1 [[TMP1:%.*]], i1 [[TMP2:%.*]])
|
|
; CHECK-NEXT: tail call void @use3-dummy(i1 [[TMP0]], i1 [[TMP1]], i1 [[TMP2]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
tail call void @use3-dummy(i1 %0, i1 %1, i1 %2)
|
|
ret void
|
|
}
|
|
|
|
; TEST0 icmp test
|
|
define void @test0-icmp-check(i32* %p){
|
|
; ret = [0, 10)
|
|
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test0-icmp-check
|
|
; IS__TUNIT_OPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
|
|
; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #3, !range !0
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0
|
|
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 false, i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]])
|
|
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 false)
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0
|
|
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 true, i1 [[CMP_NE_2]], i1 [[CMP_NE_3]])
|
|
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 true)
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0
|
|
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 false, i1 false, i1 [[CMP_UGT_3]])
|
|
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 false)
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1
|
|
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 false, i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]])
|
|
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 true, i1 false)
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0
|
|
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 false, i1 false, i1 [[CMP_SGT_3]])
|
|
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 true)
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1
|
|
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 false, i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]])
|
|
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 true, i1 true)
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1
|
|
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 true, i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]])
|
|
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 false, i1 false)
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1
|
|
; IS__TUNIT_OPM-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0
|
|
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 true, i1 true, i1 [[CMP_LTE_3]])
|
|
; IS__TUNIT_OPM-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 false)
|
|
; IS__TUNIT_OPM-NEXT: ret void
|
|
;
|
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test0-icmp-check
|
|
; IS__TUNIT_NPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
|
|
; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #2, !range !0
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0
|
|
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 false, i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]])
|
|
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 false)
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0
|
|
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 true, i1 [[CMP_NE_2]], i1 [[CMP_NE_3]])
|
|
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 true)
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0
|
|
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 false, i1 false, i1 [[CMP_UGT_3]])
|
|
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 false)
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1
|
|
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 false, i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]])
|
|
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 true, i1 false)
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0
|
|
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 false, i1 false, i1 [[CMP_SGT_3]])
|
|
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 true)
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1
|
|
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 false, i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]])
|
|
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 true, i1 true)
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1
|
|
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 true, i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]])
|
|
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 false, i1 false)
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1
|
|
; IS__TUNIT_NPM-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0
|
|
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 true, i1 true, i1 [[CMP_LTE_3]])
|
|
; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 false)
|
|
; IS__TUNIT_NPM-NEXT: ret void
|
|
;
|
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test0-icmp-check
|
|
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
|
|
; IS__CGSCC____-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]])
|
|
; IS__CGSCC____-NEXT: [[CMP_EQ_1:%.*]] = icmp eq i32 [[RET]], 10
|
|
; IS__CGSCC____-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
|
|
; IS__CGSCC____-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
|
|
; IS__CGSCC____-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1
|
|
; IS__CGSCC____-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0
|
|
; IS__CGSCC____-NEXT: [[CMP_EQ_6:%.*]] = icmp eq i32 [[RET]], -1
|
|
; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_EQ_1]], i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]])
|
|
; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 [[CMP_EQ_6]])
|
|
; IS__CGSCC____-NEXT: [[CMP_NE_1:%.*]] = icmp ne i32 [[RET]], 10
|
|
; IS__CGSCC____-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9
|
|
; IS__CGSCC____-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8
|
|
; IS__CGSCC____-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1
|
|
; IS__CGSCC____-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0
|
|
; IS__CGSCC____-NEXT: [[CMP_NE_6:%.*]] = icmp ne i32 [[RET]], -1
|
|
; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_NE_1]], i1 [[CMP_NE_2]], i1 [[CMP_NE_3]])
|
|
; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 [[CMP_NE_6]])
|
|
; IS__CGSCC____-NEXT: [[CMP_UGT_1:%.*]] = icmp ugt i32 [[RET]], 10
|
|
; IS__CGSCC____-NEXT: [[CMP_UGT_2:%.*]] = icmp ugt i32 [[RET]], 9
|
|
; IS__CGSCC____-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8
|
|
; IS__CGSCC____-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1
|
|
; IS__CGSCC____-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0
|
|
; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_UGT_1]], i1 [[CMP_UGT_2]], i1 [[CMP_UGT_3]])
|
|
; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 false)
|
|
; IS__CGSCC____-NEXT: [[CMP_UGE_1:%.*]] = icmp uge i32 [[RET]], 10
|
|
; IS__CGSCC____-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9
|
|
; IS__CGSCC____-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8
|
|
; IS__CGSCC____-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1
|
|
; IS__CGSCC____-NEXT: [[CMP_UGE_6:%.*]] = icmp uge i32 [[RET]], -1
|
|
; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_UGE_1]], i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]])
|
|
; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 true, i1 [[CMP_UGE_6]])
|
|
; IS__CGSCC____-NEXT: [[CMP_SGT_1:%.*]] = icmp sgt i32 [[RET]], 10
|
|
; IS__CGSCC____-NEXT: [[CMP_SGT_2:%.*]] = icmp sgt i32 [[RET]], 9
|
|
; IS__CGSCC____-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8
|
|
; IS__CGSCC____-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1
|
|
; IS__CGSCC____-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0
|
|
; IS__CGSCC____-NEXT: [[CMP_SGT_6:%.*]] = icmp sgt i32 [[RET]], -1
|
|
; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_SGT_1]], i1 [[CMP_SGT_2]], i1 [[CMP_SGT_3]])
|
|
; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 [[CMP_SGT_6]])
|
|
; IS__CGSCC____-NEXT: [[CMP_GTE_1:%.*]] = icmp sge i32 [[RET]], 10
|
|
; IS__CGSCC____-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9
|
|
; IS__CGSCC____-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8
|
|
; IS__CGSCC____-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1
|
|
; IS__CGSCC____-NEXT: [[CMP_GTE_5:%.*]] = icmp sge i32 [[RET]], 0
|
|
; IS__CGSCC____-NEXT: [[CMP_GTE_6:%.*]] = icmp sge i32 [[RET]], -1
|
|
; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_GTE_1]], i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]])
|
|
; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 [[CMP_GTE_5]], i1 [[CMP_GTE_6]])
|
|
; IS__CGSCC____-NEXT: [[CMP_SLT_1:%.*]] = icmp slt i32 [[RET]], 10
|
|
; IS__CGSCC____-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9
|
|
; IS__CGSCC____-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8
|
|
; IS__CGSCC____-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1
|
|
; IS__CGSCC____-NEXT: [[CMP_SLT_5:%.*]] = icmp slt i32 [[RET]], 0
|
|
; IS__CGSCC____-NEXT: [[CMP_SLT_6:%.*]] = icmp slt i32 [[RET]], -1
|
|
; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_SLT_1]], i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]])
|
|
; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 [[CMP_SLT_5]], i1 [[CMP_SLT_6]])
|
|
; IS__CGSCC____-NEXT: [[CMP_LTE_1:%.*]] = icmp sle i32 [[RET]], 10
|
|
; IS__CGSCC____-NEXT: [[CMP_LTE_2:%.*]] = icmp sle i32 [[RET]], 9
|
|
; IS__CGSCC____-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8
|
|
; IS__CGSCC____-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1
|
|
; IS__CGSCC____-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0
|
|
; IS__CGSCC____-NEXT: [[CMP_LTE_6:%.*]] = icmp sle i32 [[RET]], -1
|
|
; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_LTE_1]], i1 [[CMP_LTE_2]], i1 [[CMP_LTE_3]])
|
|
; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 [[CMP_LTE_6]])
|
|
; IS__CGSCC____-NEXT: ret void
|
|
;
|
|
%ret = tail call i32 @test0(i32 *%p)
|
|
|
|
; ret = [0, 10), eq
|
|
%cmp-eq-1 = icmp eq i32 %ret, 10
|
|
%cmp-eq-2 = icmp eq i32 %ret, 9
|
|
%cmp-eq-3 = icmp eq i32 %ret, 8
|
|
%cmp-eq-4 = icmp eq i32 %ret, 1
|
|
%cmp-eq-5 = icmp eq i32 %ret, 0
|
|
%cmp-eq-6 = icmp eq i32 %ret, -1
|
|
tail call void @use3(i1 %cmp-eq-1, i1 %cmp-eq-2, i1 %cmp-eq-3)
|
|
tail call void @use3(i1 %cmp-eq-4, i1 %cmp-eq-5, i1 %cmp-eq-6)
|
|
|
|
; ret = [0, 10), ne
|
|
%cmp-ne-1 = icmp ne i32 %ret, 10
|
|
%cmp-ne-2 = icmp ne i32 %ret, 9
|
|
%cmp-ne-3 = icmp ne i32 %ret, 8
|
|
%cmp-ne-4 = icmp ne i32 %ret, 1
|
|
%cmp-ne-5 = icmp ne i32 %ret, 0
|
|
%cmp-ne-6 = icmp ne i32 %ret, -1
|
|
tail call void @use3(i1 %cmp-ne-1, i1 %cmp-ne-2, i1 %cmp-ne-3)
|
|
tail call void @use3(i1 %cmp-ne-4, i1 %cmp-ne-5, i1 %cmp-ne-6)
|
|
|
|
; ret = [0, 10), ugt
|
|
%cmp-ugt-1 = icmp ugt i32 %ret, 10
|
|
%cmp-ugt-2 = icmp ugt i32 %ret, 9
|
|
%cmp-ugt-3 = icmp ugt i32 %ret, 8
|
|
%cmp-ugt-4 = icmp ugt i32 %ret, 1
|
|
%cmp-ugt-5 = icmp ugt i32 %ret, 0
|
|
%cmp-ugt-6 = icmp ugt i32 %ret, -1
|
|
tail call void @use3(i1 %cmp-ugt-1, i1 %cmp-ugt-2, i1 %cmp-ugt-3)
|
|
tail call void @use3(i1 %cmp-ugt-4, i1 %cmp-ugt-5, i1 %cmp-ugt-6)
|
|
|
|
; ret = [0, 10), uge
|
|
%cmp-uge-1 = icmp uge i32 %ret, 10
|
|
%cmp-uge-2 = icmp uge i32 %ret, 9
|
|
%cmp-uge-3 = icmp uge i32 %ret, 8
|
|
%cmp-uge-4 = icmp uge i32 %ret, 1
|
|
%cmp-uge-5 = icmp uge i32 %ret, 0
|
|
%cmp-uge-6 = icmp uge i32 %ret, -1
|
|
tail call void @use3(i1 %cmp-uge-1, i1 %cmp-uge-2, i1 %cmp-uge-3)
|
|
tail call void @use3(i1 %cmp-uge-4, i1 %cmp-uge-5, i1 %cmp-uge-6)
|
|
|
|
; ret = [0, 10), sgt
|
|
%cmp-sgt-1 = icmp sgt i32 %ret, 10
|
|
%cmp-sgt-2 = icmp sgt i32 %ret, 9
|
|
%cmp-sgt-3 = icmp sgt i32 %ret, 8
|
|
%cmp-sgt-4 = icmp sgt i32 %ret, 1
|
|
%cmp-sgt-5 = icmp sgt i32 %ret, 0
|
|
%cmp-sgt-6 = icmp sgt i32 %ret, -1
|
|
tail call void @use3(i1 %cmp-sgt-1, i1 %cmp-sgt-2, i1 %cmp-sgt-3)
|
|
tail call void @use3(i1 %cmp-sgt-4, i1 %cmp-sgt-5, i1 %cmp-sgt-6)
|
|
|
|
; ret = [0, 10), sge
|
|
%cmp-gte-1 = icmp sge i32 %ret, 10
|
|
%cmp-gte-2 = icmp sge i32 %ret, 9
|
|
%cmp-gte-3 = icmp sge i32 %ret, 8
|
|
%cmp-gte-4 = icmp sge i32 %ret, 1
|
|
%cmp-gte-5 = icmp sge i32 %ret, 0
|
|
%cmp-gte-6 = icmp sge i32 %ret, -1
|
|
tail call void @use3(i1 %cmp-gte-1, i1 %cmp-gte-2, i1 %cmp-gte-3)
|
|
tail call void @use3(i1 %cmp-gte-4, i1 %cmp-gte-5, i1 %cmp-gte-6)
|
|
|
|
; ret = [0, 10), slt
|
|
%cmp-slt-1 = icmp slt i32 %ret, 10
|
|
%cmp-slt-2 = icmp slt i32 %ret, 9
|
|
%cmp-slt-3 = icmp slt i32 %ret, 8
|
|
%cmp-slt-4 = icmp slt i32 %ret, 1
|
|
%cmp-slt-5 = icmp slt i32 %ret, 0
|
|
%cmp-slt-6 = icmp slt i32 %ret, -1
|
|
tail call void @use3(i1 %cmp-slt-1, i1 %cmp-slt-2, i1 %cmp-slt-3)
|
|
tail call void @use3(i1 %cmp-slt-4, i1 %cmp-slt-5, i1 %cmp-slt-6)
|
|
|
|
; ret = [0, 10), sle
|
|
%cmp-lte-1 = icmp sle i32 %ret, 10
|
|
%cmp-lte-2 = icmp sle i32 %ret, 9
|
|
%cmp-lte-3 = icmp sle i32 %ret, 8
|
|
%cmp-lte-4 = icmp sle i32 %ret, 1
|
|
%cmp-lte-5 = icmp sle i32 %ret, 0
|
|
%cmp-lte-6 = icmp sle i32 %ret, -1
|
|
tail call void @use3(i1 %cmp-lte-1, i1 %cmp-lte-2, i1 %cmp-lte-3)
|
|
tail call void @use3(i1 %cmp-lte-4, i1 %cmp-lte-5, i1 %cmp-lte-6)
|
|
|
|
ret void
|
|
}
|
|
define i32 @test1(i32* %p) {
|
|
; CHECK-LABEL: define {{[^@]+}}@test1
|
|
; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
|
|
; CHECK-NEXT: [[LOAD_10_100:%.*]] = load i32, i32* [[P]], align 4, !range !1
|
|
; CHECK-NEXT: [[ADD_10_THEN_20_110:%.*]] = add i32 [[LOAD_10_100]], 10
|
|
; CHECK-NEXT: [[MUL_10_THEN_200_1091:%.*]] = mul i32 [[ADD_10_THEN_20_110]], 10
|
|
; CHECK-NEXT: ret i32 [[MUL_10_THEN_200_1091]]
|
|
;
|
|
%load-10-100 = load i32, i32* %p, !range !1
|
|
%add-10-then-20-110 = add i32 %load-10-100, 10
|
|
%mul-10-then-200-1091 = mul i32 %add-10-then-20-110, 10
|
|
ret i32 %mul-10-then-200-1091
|
|
}
|
|
|
|
define i1 @test1-check(i32* %p) {
|
|
;
|
|
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test1-check
|
|
; IS__TUNIT_OPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
|
|
; IS__TUNIT_OPM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree readonly align 4 [[P]]) #3, !range !2
|
|
; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500
|
|
; IS__TUNIT_OPM-NEXT: ret i1 [[CMP]]
|
|
;
|
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test1-check
|
|
; IS__TUNIT_NPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
|
|
; IS__TUNIT_NPM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree readonly align 4 [[P]]) #2, !range !2
|
|
; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500
|
|
; IS__TUNIT_NPM-NEXT: ret i1 [[CMP]]
|
|
;
|
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test1-check
|
|
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
|
|
; IS__CGSCC____-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]])
|
|
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500
|
|
; IS__CGSCC____-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%res = tail call i32 @test1(i32* %p)
|
|
%cmp = icmp eq i32 %res, 500
|
|
ret i1 %cmp
|
|
}
|
|
|
|
; TEST2
|
|
; int test2(int *p) { return *p == 0 ? 4 : 3; }
|
|
; int test2_check(int *p) {
|
|
; int call = test2(p);
|
|
; if (call == 5) {
|
|
; // dead block
|
|
; return 2;
|
|
; } else {
|
|
; return 3;
|
|
; }
|
|
; }
|
|
|
|
define i32 @test2(i32* %p) {
|
|
; CHECK-LABEL: define {{[^@]+}}@test2
|
|
; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[P]], align 4
|
|
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 4, i32 3
|
|
; CHECK-NEXT: ret i32 [[COND]]
|
|
;
|
|
entry:
|
|
%0 = load i32, i32* %p, align 4
|
|
%tobool = icmp eq i32 %0, 0
|
|
%cond = select i1 %tobool, i32 4, i32 3
|
|
ret i32 %cond
|
|
}
|
|
|
|
define i32 @test2_check(i32* %p) {
|
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_check
|
|
; IS__TUNIT____-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
|
|
; IS__TUNIT____-NEXT: entry:
|
|
; IS__TUNIT____-NEXT: br label [[IF_THEN:%.*]]
|
|
; IS__TUNIT____: if.then:
|
|
; IS__TUNIT____-NEXT: br label [[RETURN:%.*]]
|
|
; IS__TUNIT____: if.end:
|
|
; IS__TUNIT____-NEXT: unreachable
|
|
; IS__TUNIT____: return:
|
|
; IS__TUNIT____-NEXT: ret i32 2
|
|
;
|
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test2_check
|
|
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
|
|
; IS__CGSCC____-NEXT: entry:
|
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = tail call i32 @test2(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]])
|
|
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 5
|
|
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
|
; IS__CGSCC____: if.then:
|
|
; IS__CGSCC____-NEXT: br label [[RETURN:%.*]]
|
|
; IS__CGSCC____: if.end:
|
|
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
|
; IS__CGSCC____: return:
|
|
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 2, [[IF_THEN]] ], [ 3, [[IF_END]] ]
|
|
; IS__CGSCC____-NEXT: ret i32 [[RETVAL_0]]
|
|
;
|
|
entry:
|
|
%call = tail call i32 @test2(i32* %p)
|
|
%cmp = icmp slt i32 %call, 5
|
|
br i1 %cmp, label %if.then, label %if.end
|
|
|
|
if.then: ; preds = %entry
|
|
br label %return
|
|
|
|
if.end: ; preds = %entry
|
|
br label %return
|
|
|
|
return: ; preds = %if.end, %if.then
|
|
%retval.0 = phi i32 [ 2, %if.then ], [ 3, %if.end ]
|
|
ret i32 %retval.0
|
|
}
|
|
|
|
; TEST 3 SECV test
|
|
|
|
; void unkown();
|
|
; int r1(unsigned int u){
|
|
; int sum = 0;
|
|
; for(int i = 0; i<100;i++){
|
|
; sum += i;
|
|
; }
|
|
; // sum = 50 * 49 / 2
|
|
; if(sum > 10000){
|
|
; // dead block
|
|
; return 20;
|
|
; }else {
|
|
; return 10;
|
|
; }
|
|
; }
|
|
; void f1(int u){
|
|
; if(r1(u) > 15){
|
|
; // deadblock
|
|
; unkown();
|
|
; }else {
|
|
; return;
|
|
; }
|
|
; }
|
|
|
|
declare dso_local void @unkown()
|
|
|
|
define internal i32 @r1(i32) local_unnamed_addr {
|
|
; IS________OPM-LABEL: define {{[^@]+}}@r1() local_unnamed_addr
|
|
; IS________OPM-NEXT: br label [[TMP4:%.*]]
|
|
; IS________OPM: 1:
|
|
; IS________OPM-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP7:%.*]], 10000
|
|
; IS________OPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[F:%.*]]
|
|
; IS________OPM: 3:
|
|
; IS________OPM-NEXT: ret i32 20
|
|
; IS________OPM: f:
|
|
; IS________OPM-NEXT: ret i32 10
|
|
; IS________OPM: 4:
|
|
; IS________OPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[TMP8:%.*]], [[TMP4]] ]
|
|
; IS________OPM-NEXT: [[TMP6:%.*]] = phi i32 [ 0, [[TMP0]] ], [ [[TMP7]], [[TMP4]] ]
|
|
; IS________OPM-NEXT: [[TMP7]] = add nuw nsw i32 [[TMP5]], [[TMP6]]
|
|
; IS________OPM-NEXT: [[TMP8]] = add nuw nsw i32 [[TMP5]], 1
|
|
; IS________OPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 100
|
|
; IS________OPM-NEXT: br i1 [[TMP9]], label [[TMP1:%.*]], label [[TMP4]]
|
|
;
|
|
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@r1() local_unnamed_addr
|
|
; IS__CGSCC_NPM-NEXT: br label [[TMP3:%.*]]
|
|
; IS__CGSCC_NPM: 1:
|
|
; IS__CGSCC_NPM-NEXT: br label [[F:%.*]]
|
|
; IS__CGSCC_NPM: 2:
|
|
; IS__CGSCC_NPM-NEXT: unreachable
|
|
; IS__CGSCC_NPM: f:
|
|
; IS__CGSCC_NPM-NEXT: ret i32 10
|
|
; IS__CGSCC_NPM: 3:
|
|
; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[TMP7:%.*]], [[TMP3]] ]
|
|
; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP0]] ], [ [[TMP6:%.*]], [[TMP3]] ]
|
|
; IS__CGSCC_NPM-NEXT: [[TMP6]] = add nuw nsw i32 [[TMP4]], [[TMP5]]
|
|
; IS__CGSCC_NPM-NEXT: [[TMP7]] = add nuw nsw i32 [[TMP4]], 1
|
|
; IS__CGSCC_NPM-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 100
|
|
; IS__CGSCC_NPM-NEXT: br i1 [[TMP8]], label [[TMP1:%.*]], label [[TMP3]]
|
|
;
|
|
br label %5
|
|
|
|
2: ; preds = %5
|
|
%3 = icmp sgt i32 %8, 10000
|
|
br i1 %3, label %4, label %f
|
|
4:
|
|
ret i32 20
|
|
f:
|
|
ret i32 10
|
|
5: ; preds = %5, %1
|
|
%6 = phi i32 [ 0, %1 ], [ %9, %5 ]
|
|
%7 = phi i32 [ 0, %1 ], [ %8, %5 ]
|
|
%8 = add nuw nsw i32 %6, %7
|
|
%9 = add nuw nsw i32 %6, 1
|
|
%10 = icmp eq i32 %9, 100
|
|
br i1 %10, label %2, label %5
|
|
}
|
|
|
|
define void @f1(i32){
|
|
; IS________OPM-LABEL: define {{[^@]+}}@f1
|
|
; IS________OPM-SAME: (i32 [[TMP0:%.*]])
|
|
; IS________OPM-NEXT: [[TMP2:%.*]] = tail call i32 @r1()
|
|
; IS________OPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15
|
|
; IS________OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
|
|
; IS________OPM: 4:
|
|
; IS________OPM-NEXT: tail call void @unkown()
|
|
; IS________OPM-NEXT: br label [[TMP5]]
|
|
; IS________OPM: 5:
|
|
; IS________OPM-NEXT: ret void
|
|
;
|
|
; IS________NPM-LABEL: define {{[^@]+}}@f1
|
|
; IS________NPM-SAME: (i32 [[TMP0:%.*]])
|
|
; IS________NPM-NEXT: br label [[TMP3:%.*]]
|
|
; IS________NPM: 2:
|
|
; IS________NPM-NEXT: unreachable
|
|
; IS________NPM: 3:
|
|
; IS________NPM-NEXT: ret void
|
|
;
|
|
%2 = tail call i32 @r1(i32 %0)
|
|
%3 = icmp sgt i32 %2, 15
|
|
br i1 %3, label %4, label %5
|
|
|
|
4: ; preds = %1
|
|
tail call void @unkown()
|
|
br label %5
|
|
|
|
5: ; preds = %1, %4
|
|
ret void
|
|
}
|
|
|
|
; TEST4 LVI test
|
|
|
|
; f1
|
|
; int test4-f1(int u){
|
|
; if(u>=0) {
|
|
; return u;
|
|
; }else{
|
|
; return 0;
|
|
; }
|
|
; }
|
|
define dso_local i32 @test4-f1(i32 %u) {
|
|
; CHECK-LABEL: define {{[^@]+}}@test4-f1
|
|
; CHECK-SAME: (i32 [[U:%.*]])
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: br label [[RETURN]]
|
|
; CHECK: return:
|
|
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]
|
|
; CHECK-NEXT: ret i32 [[RETVAL_0]]
|
|
;
|
|
; FIXME: RETVAL_0 >= 0
|
|
entry:
|
|
%cmp = icmp sgt i32 %u, -1
|
|
br i1 %cmp, label %if.then, label %return
|
|
|
|
if.then: ; preds = %entry
|
|
br label %return
|
|
|
|
return: ; preds = %entry, %if.then
|
|
%retval.0 = phi i32 [ %u, %if.then ], [ 0, %entry ]
|
|
ret i32 %retval.0
|
|
}
|
|
|
|
|
|
define dso_local i32 @test4-g1(i32 %u) {
|
|
; CHECK-LABEL: define {{[^@]+}}@test4-g1
|
|
; CHECK-SAME: (i32 [[U:%.*]])
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]])
|
|
; CHECK-NEXT: ret i32 [[CALL]]
|
|
;
|
|
; FIXME: %call should have range [0, inf]
|
|
|
|
entry:
|
|
%call = tail call i32 @test4-f1(i32 %u)
|
|
ret i32 %call
|
|
}
|
|
|
|
; f2
|
|
; int test4-f1(int u){
|
|
; if(u>-1) {
|
|
; return u+1;
|
|
; }else{
|
|
; return 1;
|
|
; }
|
|
; }
|
|
define dso_local i32 @test4-f2(i32 %u) {
|
|
; CHECK-LABEL: define {{[^@]+}}@test4-f2
|
|
; CHECK-SAME: (i32 [[U:%.*]])
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[U]], 1
|
|
; CHECK-NEXT: br label [[RETURN:%.*]]
|
|
; CHECK: if.else:
|
|
; CHECK-NEXT: br label [[RETURN]]
|
|
; CHECK: return:
|
|
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ]
|
|
; CHECK-NEXT: ret i32 [[RETVAL_0]]
|
|
;
|
|
entry:
|
|
%cmp = icmp sgt i32 %u, -1
|
|
br i1 %cmp, label %if.then, label %if.else
|
|
|
|
if.then: ; preds = %entry
|
|
%add = add nuw nsw i32 %u, 1
|
|
br label %return
|
|
|
|
if.else: ; preds = %entry
|
|
br label %return
|
|
|
|
return: ; preds = %if.else, %if.then
|
|
%retval.0 = phi i32 [ %add, %if.then ], [ 1, %if.else ]
|
|
ret i32 %retval.0
|
|
}
|
|
|
|
|
|
define dso_local i32 @test4-g2(i32 %u) {
|
|
; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@test4-g2
|
|
; NOT_TUNIT_NPM-SAME: (i32 [[U:%.*]])
|
|
; NOT_TUNIT_NPM-NEXT: entry:
|
|
; NOT_TUNIT_NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]])
|
|
; NOT_TUNIT_NPM-NEXT: ret i32 [[CALL]]
|
|
;
|
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test4-g2
|
|
; IS__TUNIT_NPM-SAME: (i32 [[U:%.*]])
|
|
; IS__TUNIT_NPM-NEXT: entry:
|
|
; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #1, !range !3
|
|
; IS__TUNIT_NPM-NEXT: ret i32 [[CALL]]
|
|
;
|
|
entry:
|
|
%call = tail call i32 @test4-f2(i32 %u)
|
|
ret i32 %call
|
|
}
|
|
|
|
define dso_local i32 @test-5() {
|
|
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test-5()
|
|
; IS__TUNIT_OPM-NEXT: entry:
|
|
; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @rec(i32 0), !range !3
|
|
; IS__TUNIT_OPM-NEXT: ret i32 [[CALL]]
|
|
;
|
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test-5()
|
|
; IS__TUNIT_NPM-NEXT: entry:
|
|
; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32 @rec(i32 0), !range !4
|
|
; IS__TUNIT_NPM-NEXT: ret i32 [[CALL]]
|
|
;
|
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test-5()
|
|
; IS__CGSCC____-NEXT: entry:
|
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @rec(i32 0)
|
|
; IS__CGSCC____-NEXT: ret i32 [[CALL]]
|
|
;
|
|
entry:
|
|
%call = call i32 @rec(i32 0)
|
|
ret i32 %call
|
|
}
|
|
define internal i32 @rec(i32 %depth) {
|
|
; CHECK-LABEL: define {{[^@]+}}@rec
|
|
; CHECK-SAME: (i32 [[DEPTH:%.*]])
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo(i32 [[DEPTH]])
|
|
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[CALL]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: br label [[RETURN:%.*]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[DEPTH]], 10
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END3:%.*]]
|
|
; CHECK: if.then1:
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[DEPTH]], 1
|
|
; CHECK-NEXT: [[CALL2:%.*]] = call i32 @rec(i32 [[ADD]])
|
|
; CHECK-NEXT: br label [[IF_END3]]
|
|
; CHECK: if.end3:
|
|
; CHECK-NEXT: br label [[RETURN]]
|
|
; CHECK: return:
|
|
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 0, [[IF_THEN]] ], [ 1, [[IF_END3]] ]
|
|
; CHECK-NEXT: ret i32 [[RETVAL_0]]
|
|
;
|
|
entry:
|
|
%call = call i32 @foo(i32 %depth)
|
|
%tobool = icmp ne i32 %call, 0
|
|
br i1 %tobool, label %if.then, label %if.end
|
|
|
|
if.then: ; preds = %entry
|
|
br label %return
|
|
|
|
if.end: ; preds = %entry
|
|
%cmp = icmp slt i32 %depth, 10
|
|
br i1 %cmp, label %if.then1, label %if.end3
|
|
|
|
if.then1: ; preds = %if.end
|
|
%add = add nsw i32 %depth, 1
|
|
%call2 = call i32 @rec(i32 %add)
|
|
br label %if.end3
|
|
|
|
if.end3: ; preds = %if.then1, %if.end
|
|
br label %return
|
|
|
|
return: ; preds = %if.end3, %if.then
|
|
%retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.end3 ]
|
|
ret i32 %retval.0
|
|
}
|
|
declare dso_local i32 @foo(i32)
|
|
|
|
|
|
; Examples taken from https://llvm.discourse.group/t/impossible-condition-optimization/461/1
|
|
;
|
|
; The important part is that we return a constant (false)
|
|
;
|
|
; {
|
|
|
|
; FIXME: All but the return is not needed anymore
|
|
define dso_local zeroext i1 @phi(i32 %arg) {
|
|
; CHECK-LABEL: define {{[^@]+}}@phi
|
|
; CHECK-SAME: (i32 [[ARG:%.*]])
|
|
; CHECK-NEXT: bb:
|
|
; CHECK-NEXT: [[TMP:%.*]] = icmp sgt i32 [[ARG]], 5
|
|
; CHECK-NEXT: br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]]
|
|
; CHECK: bb1:
|
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
|
; CHECK: bb2:
|
|
; CHECK-NEXT: br label [[BB3]]
|
|
; CHECK: bb3:
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[ARG]], 10
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[BB5:%.*]], label [[BB7:%.*]]
|
|
; CHECK: bb5:
|
|
; CHECK-NEXT: br label [[BB9:%.*]]
|
|
; CHECK: bb7:
|
|
; CHECK-NEXT: br label [[BB9]]
|
|
; CHECK: bb9:
|
|
; CHECK-NEXT: br label [[BB12:%.*]]
|
|
; CHECK: bb11:
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: bb12:
|
|
; CHECK-NEXT: br label [[BB13:%.*]]
|
|
; CHECK: bb13:
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
bb:
|
|
%tmp = icmp sgt i32 %arg, 5
|
|
br i1 %tmp, label %bb1, label %bb2
|
|
|
|
bb1: ; preds = %bb
|
|
br label %bb3
|
|
|
|
bb2: ; preds = %bb
|
|
br label %bb3
|
|
|
|
bb3: ; preds = %bb2, %bb1
|
|
%.02 = phi i32 [ 1, %bb1 ], [ 2, %bb2 ]
|
|
%tmp4 = icmp sgt i32 %arg, 10
|
|
br i1 %tmp4, label %bb5, label %bb7
|
|
|
|
bb5: ; preds = %bb3
|
|
%tmp6 = add nsw i32 %.02, 1
|
|
br label %bb9
|
|
|
|
bb7: ; preds = %bb3
|
|
%tmp8 = add nsw i32 %.02, 2
|
|
br label %bb9
|
|
|
|
bb9: ; preds = %bb7, %bb5
|
|
%.01 = phi i32 [ %tmp6, %bb5 ], [ %tmp8, %bb7 ]
|
|
%tmp10 = icmp eq i32 %.01, 5
|
|
br i1 %tmp10, label %bb11, label %bb12
|
|
|
|
bb11: ; preds = %bb9
|
|
br label %bb13
|
|
|
|
bb12: ; preds = %bb9
|
|
br label %bb13
|
|
|
|
bb13: ; preds = %bb12, %bb11
|
|
%.0 = phi i1 [ true, %bb11 ], [ false, %bb12 ]
|
|
ret i1 %.0
|
|
}
|
|
|
|
define dso_local i1 @select(i32 %a) local_unnamed_addr #0 {
|
|
; CHECK-LABEL: define {{[^@]+}}@select
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
entry:
|
|
%cmp = icmp sgt i32 %a, 5
|
|
%. = select i1 %cmp, i32 1, i32 2
|
|
%cmp1 = icmp sgt i32 %a, 10
|
|
%y.0.v = select i1 %cmp1, i32 1, i32 2
|
|
%y.0 = add nuw nsw i32 %., %y.0.v
|
|
%cmp6 = icmp eq i32 %y.0, 5
|
|
ret i1 %cmp6
|
|
}
|
|
|
|
define dso_local i32 @select_zext(i32 %a) local_unnamed_addr #0 {
|
|
; CHECK-LABEL: define {{[^@]+}}@select_zext
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: ret i32 0
|
|
;
|
|
entry:
|
|
%cmp = icmp sgt i32 %a, 5
|
|
%. = select i1 %cmp, i32 1, i32 2
|
|
%cmp1 = icmp sgt i32 %a, 10
|
|
%y.0.v = select i1 %cmp1, i32 1, i32 2
|
|
%y.0 = add nuw nsw i32 %., %y.0.v
|
|
%cmp6 = icmp eq i32 %y.0, 5
|
|
%.13 = zext i1 %cmp6 to i32
|
|
ret i32 %.13
|
|
}
|
|
|
|
; FIXME: We do not look through the ptr casts here.
|
|
define dso_local i64 @select_int2ptr_bitcast_ptr2int(i32 %a) local_unnamed_addr #0 {
|
|
; CHECK-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[I2P:%.*]] = inttoptr i1 false to i1*
|
|
; CHECK-NEXT: [[BC:%.*]] = bitcast i1* [[I2P]] to i32*
|
|
; CHECK-NEXT: [[P2I:%.*]] = ptrtoint i32* [[BC]] to i64
|
|
; CHECK-NEXT: ret i64 [[P2I]]
|
|
;
|
|
entry:
|
|
%cmp = icmp sgt i32 %a, 5
|
|
%. = select i1 %cmp, i32 1, i32 2
|
|
%cmp1 = icmp sgt i32 %a, 10
|
|
%y.0.v = select i1 %cmp1, i32 1, i32 2
|
|
%y.0 = add nuw nsw i32 %., %y.0.v
|
|
%cmp6 = icmp eq i32 %y.0, 5
|
|
%i2p = inttoptr i1 %cmp6 to i1*
|
|
%bc = bitcast i1* %i2p to i32*
|
|
%p2i = ptrtoint i32* %bc to i64
|
|
ret i64 %p2i
|
|
}
|
|
|
|
; }
|
|
|
|
define i1 @f_fcmp(float %a, float %b) {
|
|
; CHECK-LABEL: define {{[^@]+}}@f_fcmp
|
|
; CHECK-SAME: (float [[A:%.*]], float [[B:%.*]])
|
|
; CHECK-NEXT: [[R:%.*]] = fcmp uge float [[A]], [[B]]
|
|
; CHECK-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
|
|
; CHECK-NEXT: ret i1 [[S]]
|
|
;
|
|
%r = fcmp uge float %a, %b
|
|
%s = select i1 %r, i1 %r, i1 0
|
|
ret i1 %s
|
|
}
|
|
define i1 @d_fcmp(double %a, double %b) {
|
|
; CHECK-LABEL: define {{[^@]+}}@d_fcmp
|
|
; CHECK-SAME: (double [[A:%.*]], double [[B:%.*]])
|
|
; CHECK-NEXT: [[R:%.*]] = fcmp oeq double [[A]], [[B]]
|
|
; CHECK-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
|
|
; CHECK-NEXT: ret i1 [[S]]
|
|
;
|
|
%r = fcmp oeq double %a, %b
|
|
%s = select i1 %r, i1 %r, i1 0
|
|
ret i1 %s
|
|
}
|
|
define i1 @dp_icmp(double* %a, double* %b) {
|
|
; CHECK-LABEL: define {{[^@]+}}@dp_icmp
|
|
; CHECK-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]])
|
|
; CHECK-NEXT: [[R:%.*]] = icmp sge double* [[A]], [[B]]
|
|
; CHECK-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
|
|
; CHECK-NEXT: ret i1 [[S]]
|
|
;
|
|
%r = icmp sge double* %a, %b
|
|
%s = select i1 %r, i1 %r, i1 0
|
|
ret i1 %s
|
|
}
|
|
define i1 @ip_icmp(i8* %a, i8* %b) {
|
|
; CHECK-LABEL: define {{[^@]+}}@ip_icmp
|
|
; CHECK-SAME: (i8* nofree readnone [[A:%.*]], i8* nofree readnone [[B:%.*]])
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ult i8* [[A]], [[B]]
|
|
; CHECK-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
|
|
; CHECK-NEXT: ret i1 [[S]]
|
|
;
|
|
%r = icmp ult i8* %a, %b
|
|
%s = select i1 %r, i1 %r, i1 0
|
|
ret i1 %s
|
|
}
|
|
define i1 @fcmp_caller(float %fa, float %fb, double %da, double %db, double* %dpa, double* %dpb, i8* %ipa, i8* %ipb) {
|
|
; CHECK-LABEL: define {{[^@]+}}@fcmp_caller
|
|
; CHECK-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], double* nofree readnone [[DPA:%.*]], double* nofree readnone [[DPB:%.*]], i8* nofree readnone [[IPA:%.*]], i8* nofree readnone [[IPB:%.*]])
|
|
; CHECK-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]])
|
|
; CHECK-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]])
|
|
; CHECK-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]])
|
|
; CHECK-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]])
|
|
; CHECK-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]]
|
|
; CHECK-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]]
|
|
; CHECK-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]]
|
|
; CHECK-NEXT: ret i1 [[O3]]
|
|
;
|
|
%r1 = call i1 @f_fcmp(float %fa, float %fb)
|
|
%r2 = call i1 @d_fcmp(double %da, double %db)
|
|
%r3 = call i1 @dp_icmp(double* %dpa, double* %dpb)
|
|
%r4 = call i1 @ip_icmp(i8* %ipa, i8* %ipb)
|
|
%o1 = or i1 %r1, %r2
|
|
%o2 = or i1 %r3, %r4
|
|
%o3 = or i1 %o1, %o2
|
|
ret i1 %o3
|
|
}
|
|
|
|
define i8 @ret_two() {
|
|
; CHECK-LABEL: define {{[^@]+}}@ret_two()
|
|
; CHECK-NEXT: ret i8 2
|
|
;
|
|
ret i8 2
|
|
}
|
|
define i8 @ret_undef() {
|
|
; CHECK-LABEL: define {{[^@]+}}@ret_undef()
|
|
; CHECK-NEXT: ret i8 undef
|
|
;
|
|
ret i8 undef
|
|
}
|
|
|
|
; Verify we collapse undef to a value and return something non-undef here.
|
|
define i8 @undef_collapse_1() {
|
|
; CHECK-LABEL: define {{[^@]+}}@undef_collapse_1()
|
|
; CHECK-NEXT: ret i8 0
|
|
;
|
|
%c = call i8 @ret_undef()
|
|
%s = shl i8 %c, 2
|
|
ret i8 %s
|
|
}
|
|
|
|
; Verify we collapse undef to a value and return something non-undef here.
|
|
define i8 @undef_collapse_2() {
|
|
; CHECK-LABEL: define {{[^@]+}}@undef_collapse_2()
|
|
; CHECK-NEXT: ret i8 0
|
|
;
|
|
%c = call i8 @ret_two()
|
|
%s = shl i8 undef, %c
|
|
ret i8 %s
|
|
}
|
|
|
|
define i8 @undef_collapse_caller() {
|
|
;
|
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@undef_collapse_caller()
|
|
; IS__TUNIT____-NEXT: ret i8 0
|
|
;
|
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@undef_collapse_caller()
|
|
; IS__CGSCC____-NEXT: [[C1:%.*]] = call i8 @undef_collapse_1()
|
|
; IS__CGSCC____-NEXT: [[C2:%.*]] = call i8 @undef_collapse_2()
|
|
; IS__CGSCC____-NEXT: [[A:%.*]] = add i8 [[C1]], [[C2]]
|
|
; IS__CGSCC____-NEXT: ret i8 [[A]]
|
|
;
|
|
%c1 = call i8 @undef_collapse_1()
|
|
%c2 = call i8 @undef_collapse_2()
|
|
%a = add i8 %c1, %c2
|
|
ret i8 %a
|
|
}
|
|
|
|
define i32 @ret1or2(i1 %c) {
|
|
; CHECK-LABEL: define {{[^@]+}}@ret1or2
|
|
; CHECK-SAME: (i1 [[C:%.*]])
|
|
; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 1, i32 2
|
|
; CHECK-NEXT: ret i32 [[S]]
|
|
;
|
|
%s = select i1 %c, i32 1, i32 2
|
|
ret i32 %s
|
|
}
|
|
define i1 @callee_range_1(i1 %c1, i1 %c2, i1 %c3) {
|
|
;
|
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@callee_range_1
|
|
; IS__TUNIT____-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]])
|
|
; IS__TUNIT____-NEXT: ret i1 true
|
|
;
|
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@callee_range_1
|
|
; IS__CGSCC____-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]])
|
|
; IS__CGSCC____-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]])
|
|
; IS__CGSCC____-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]])
|
|
; IS__CGSCC____-NEXT: [[INDIRECTION:%.*]] = select i1 [[C3]], i32 [[R1]], i32 [[R2]]
|
|
; IS__CGSCC____-NEXT: [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]]
|
|
; IS__CGSCC____-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 4
|
|
; IS__CGSCC____-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
|
|
; IS__CGSCC____-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]
|
|
; IS__CGSCC____-NEXT: ret i1 [[F]]
|
|
;
|
|
%r1 = call i32 @ret1or2(i1 %c1)
|
|
%r2 = call i32 @ret1or2(i1 %c2)
|
|
%indirection = select i1 %c3, i32 %r1, i32 %r2
|
|
%a = add i32 %r1, %indirection
|
|
%i1 = icmp sle i32 %a, 4
|
|
%i2 = icmp sge i32 %a, 2
|
|
%f = and i1 %i1, %i2
|
|
ret i1 %f
|
|
}
|
|
|
|
define i1 @callee_range_2(i1 %c1, i1 %c2) {
|
|
;
|
|
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@callee_range_2
|
|
; IS__TUNIT_OPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]])
|
|
; IS__TUNIT_OPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #2, !range !4
|
|
; IS__TUNIT_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #2, !range !4
|
|
; IS__TUNIT_OPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
|
|
; IS__TUNIT_OPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
|
|
; IS__TUNIT_OPM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
|
|
; IS__TUNIT_OPM-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]
|
|
; IS__TUNIT_OPM-NEXT: ret i1 [[F]]
|
|
;
|
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_range_2
|
|
; IS__TUNIT_NPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]])
|
|
; IS__TUNIT_NPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #1, !range !5
|
|
; IS__TUNIT_NPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #1, !range !5
|
|
; IS__TUNIT_NPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
|
|
; IS__TUNIT_NPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
|
|
; IS__TUNIT_NPM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
|
|
; IS__TUNIT_NPM-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]
|
|
; IS__TUNIT_NPM-NEXT: ret i1 [[F]]
|
|
;
|
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@callee_range_2
|
|
; IS__CGSCC____-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]])
|
|
; IS__CGSCC____-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]])
|
|
; IS__CGSCC____-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]])
|
|
; IS__CGSCC____-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
|
|
; IS__CGSCC____-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
|
|
; IS__CGSCC____-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
|
|
; IS__CGSCC____-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]
|
|
; IS__CGSCC____-NEXT: ret i1 [[F]]
|
|
;
|
|
%r1 = call i32 @ret1or2(i1 %c1)
|
|
%r2 = call i32 @ret1or2(i1 %c2)
|
|
%a = add i32 %r1, %r2
|
|
%i1 = icmp sle i32 %a, 3
|
|
%i2 = icmp sge i32 %a, 2
|
|
%f = and i1 %i1, %i2
|
|
ret i1 %f
|
|
}
|
|
|
|
|
|
define i32 @ret100() {
|
|
; CHECK-LABEL: define {{[^@]+}}@ret100()
|
|
; CHECK-NEXT: ret i32 100
|
|
;
|
|
ret i32 100
|
|
}
|
|
|
|
define i1 @ctx_adjustment(i32 %V) {
|
|
;
|
|
; IS________OPM-LABEL: define {{[^@]+}}@ctx_adjustment
|
|
; IS________OPM-SAME: (i32 [[V:%.*]])
|
|
; IS________OPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100
|
|
; IS________OPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
|
|
; IS________OPM: if.true:
|
|
; IS________OPM-NEXT: br label [[END:%.*]]
|
|
; IS________OPM: if.false:
|
|
; IS________OPM-NEXT: br label [[END]]
|
|
; IS________OPM: end:
|
|
; IS________OPM-NEXT: [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ 100, [[IF_FALSE]] ]
|
|
; IS________OPM-NEXT: [[C2:%.*]] = icmp sge i32 [[PHI]], 100
|
|
; IS________OPM-NEXT: ret i1 [[C2]]
|
|
;
|
|
; IS________NPM-LABEL: define {{[^@]+}}@ctx_adjustment
|
|
; IS________NPM-SAME: (i32 [[V:%.*]])
|
|
; IS________NPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100
|
|
; IS________NPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
|
|
; IS________NPM: if.true:
|
|
; IS________NPM-NEXT: br label [[END:%.*]]
|
|
; IS________NPM: if.false:
|
|
; IS________NPM-NEXT: br label [[END]]
|
|
; IS________NPM: end:
|
|
; IS________NPM-NEXT: ret i1 true
|
|
;
|
|
%c1 = icmp sge i32 %V, 100
|
|
br i1 %c1, label %if.true, label %if.false
|
|
if.true:
|
|
br label %end
|
|
if.false:
|
|
%call = call i32 @ret100()
|
|
br label %end
|
|
end:
|
|
%phi = phi i32 [ %V, %if.true ], [ %call, %if.false ]
|
|
%c2 = icmp sge i32 %phi, 100
|
|
ret i1 %c2
|
|
}
|
|
|
|
|
|
!0 = !{i32 0, i32 10}
|
|
!1 = !{i32 10, i32 100}
|
|
|
|
; NOT_TUNIT____: !0 = !{i32 0, i32 10}
|
|
; NOT_TUNIT____: !1 = !{i32 10, i32 100}
|
|
; NOT_TUNIT____-NOT: !2
|
|
|
|
; IS__TUNIT_OPM: !0 = !{i32 0, i32 10}
|
|
; IS__TUNIT_OPM: !1 = !{i32 10, i32 100}
|
|
; IS__TUNIT_OPM: !2 = !{i32 200, i32 1091}
|
|
; IS__TUNIT_OPM: !3 = !{i32 0, i32 2}
|
|
; IS__TUNIT_OPM: !4 = !{i32 1, i32 3}
|
|
; IS__TUNIT_OPM-NOT: !5
|
|
|
|
; IS__TUNIT_NPM: !0 = !{i32 0, i32 10}
|
|
; IS__TUNIT_NPM: !1 = !{i32 10, i32 100}
|
|
; IS__TUNIT_NPM: !2 = !{i32 200, i32 1091}
|
|
; IS__TUNIT_NPM: !3 = !{i32 1, i32 -2147483648}
|
|
; IS__TUNIT_NPM: !4 = !{i32 0, i32 2}
|
|
; IS__TUNIT_NPM: !5 = !{i32 1, i32 3}
|
|
; IS__TUNIT_NPM-NOT: !6
|