llvm-project/llvm/test/Transforms/Attributor/range.ll

1804 lines
78 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=25 -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=31 -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 -enable-new-pm=0 -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) {
; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@test0
; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
; IS__TUNIT____-NEXT: [[A:%.*]] = load i32, i32* [[P]], align 4, [[RNG0:!range !.*]]
; IS__TUNIT____-NEXT: ret i32 [[A]]
;
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test0
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[P]], align 4, [[RNG0:!range !.*]]
; IS__CGSCC____-NEXT: ret i32 [[A]]
;
%a = load i32, i32* %p, !range !0
ret i32 %a
}
define i32 @test0-range-check(i32* %p) {
; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; 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]]) [[ATTR3:#.*]], [[RNG0:!range !.*]]
; IS__TUNIT_OPM-NEXT: ret i32 [[A]]
;
; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; 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]]) [[ATTR2:#.*]], [[RNG0:!range !.*]]
; IS__TUNIT_NPM-NEXT: ret i32 [[A]]
;
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; 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]]) [[ATTR3]], [[RNG0]]
; 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]]) [[ATTR2]], [[RNG0]]
; 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) {
; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@test1
; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
; IS__TUNIT____-NEXT: [[LOAD_10_100:%.*]] = load i32, i32* [[P]], align 4, [[RNG1:!range !.*]]
; IS__TUNIT____-NEXT: [[ADD_10_THEN_20_110:%.*]] = add i32 [[LOAD_10_100]], 10
; IS__TUNIT____-NEXT: [[MUL_10_THEN_200_1091:%.*]] = mul i32 [[ADD_10_THEN_20_110]], 10
; IS__TUNIT____-NEXT: ret i32 [[MUL_10_THEN_200_1091]]
;
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test1
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
; IS__CGSCC____-NEXT: [[LOAD_10_100:%.*]] = load i32, i32* [[P]], align 4, [[RNG1:!range !.*]]
; IS__CGSCC____-NEXT: [[ADD_10_THEN_20_110:%.*]] = add i32 [[LOAD_10_100]], 10
; IS__CGSCC____-NEXT: [[MUL_10_THEN_200_1091:%.*]] = mul i32 [[ADD_10_THEN_20_110]], 10
; IS__CGSCC____-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: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; 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]]) [[ATTR3]], [[RNG2:!range !.*]]
; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500
; IS__TUNIT_OPM-NEXT: ret i1 [[CMP]]
;
; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; 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]]) [[ATTR2]], [[RNG2:!range !.*]]
; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500
; IS__TUNIT_NPM-NEXT: ret i1 [[CMP]]
;
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; 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) {
; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@test2
; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[P]], align 4
; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0
; IS__TUNIT____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 4, i32 3
; IS__TUNIT____-NEXT: ret i32 [[COND]]
;
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test2
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[P]], align 4
; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0
; IS__CGSCC____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 4, i32 3
; IS__CGSCC____-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____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; 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____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; 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__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@r1() local_unnamed_addr
; IS__TUNIT_OPM-NEXT: br label [[TMP4:%.*]]
; IS__TUNIT_OPM: 1:
; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP7:%.*]], 10000
; IS__TUNIT_OPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[F:%.*]]
; IS__TUNIT_OPM: 3:
; IS__TUNIT_OPM-NEXT: ret i32 20
; IS__TUNIT_OPM: f:
; IS__TUNIT_OPM-NEXT: ret i32 10
; IS__TUNIT_OPM: 4:
; IS__TUNIT_OPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[TMP8:%.*]], [[TMP4]] ]
; IS__TUNIT_OPM-NEXT: [[TMP6:%.*]] = phi i32 [ 0, [[TMP0]] ], [ [[TMP7]], [[TMP4]] ]
; IS__TUNIT_OPM-NEXT: [[TMP7]] = add nuw nsw i32 [[TMP5]], [[TMP6]]
; IS__TUNIT_OPM-NEXT: [[TMP8]] = add nuw nsw i32 [[TMP5]], 1
; IS__TUNIT_OPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 100
; IS__TUNIT_OPM-NEXT: br i1 [[TMP9]], label [[TMP1:%.*]], label [[TMP4]]
;
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@r1() local_unnamed_addr
; IS__CGSCC_OPM-NEXT: br label [[TMP4:%.*]]
; IS__CGSCC_OPM: 1:
; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP7:%.*]], 10000
; IS__CGSCC_OPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[F:%.*]]
; IS__CGSCC_OPM: 3:
; IS__CGSCC_OPM-NEXT: ret i32 20
; IS__CGSCC_OPM: f:
; IS__CGSCC_OPM-NEXT: ret i32 10
; IS__CGSCC_OPM: 4:
; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[TMP8:%.*]], [[TMP4]] ]
; IS__CGSCC_OPM-NEXT: [[TMP6:%.*]] = phi i32 [ 0, [[TMP0]] ], [ [[TMP7]], [[TMP4]] ]
; IS__CGSCC_OPM-NEXT: [[TMP7]] = add nuw nsw i32 [[TMP5]], [[TMP6]]
; IS__CGSCC_OPM-NEXT: [[TMP8]] = add nuw nsw i32 [[TMP5]], 1
; IS__CGSCC_OPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 100
; IS__CGSCC_OPM-NEXT: br i1 [[TMP9]], label [[TMP1:%.*]], label [[TMP4]]
;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; 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__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f1
; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]])
; IS__TUNIT_NPM-NEXT: br label [[TMP3:%.*]]
; IS__TUNIT_NPM: 2:
; IS__TUNIT_NPM-NEXT: unreachable
; IS__TUNIT_NPM: 3:
; IS__TUNIT_NPM-NEXT: ret void
;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f1
; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]])
; IS__CGSCC_NPM-NEXT: br label [[TMP3:%.*]]
; IS__CGSCC_NPM: 2:
; IS__CGSCC_NPM-NEXT: unreachable
; IS__CGSCC_NPM: 3:
; IS__CGSCC_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) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@test4-f1
; IS__TUNIT____-SAME: (i32 [[U:%.*]])
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
; IS__TUNIT____: if.then:
; IS__TUNIT____-NEXT: br label [[RETURN]]
; IS__TUNIT____: return:
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]
; IS__TUNIT____-NEXT: ret i32 [[RETVAL_0]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test4-f1
; IS__CGSCC____-SAME: (i32 [[U:%.*]])
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
; IS__CGSCC____: if.then:
; IS__CGSCC____-NEXT: br label [[RETURN]]
; IS__CGSCC____: return:
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]
; IS__CGSCC____-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) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@test4-g1
; IS__TUNIT____-SAME: (i32 [[U:%.*]])
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]])
; IS__TUNIT____-NEXT: ret i32 [[CALL]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test4-g1
; IS__CGSCC____-SAME: (i32 [[U:%.*]])
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]])
; IS__CGSCC____-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) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@test4-f2
; IS__TUNIT____-SAME: (i32 [[U:%.*]])
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; IS__TUNIT____: if.then:
; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[U]], 1
; IS__TUNIT____-NEXT: br label [[RETURN:%.*]]
; IS__TUNIT____: if.else:
; IS__TUNIT____-NEXT: br label [[RETURN]]
; IS__TUNIT____: return:
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ]
; IS__TUNIT____-NEXT: ret i32 [[RETVAL_0]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test4-f2
; IS__CGSCC____-SAME: (i32 [[U:%.*]])
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; IS__CGSCC____: if.then:
; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[U]], 1
; IS__CGSCC____-NEXT: br label [[RETURN:%.*]]
; IS__CGSCC____: if.else:
; IS__CGSCC____-NEXT: br label [[RETURN]]
; IS__CGSCC____: return:
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ]
; IS__CGSCC____-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) {
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test4-g2
; IS__TUNIT_OPM-SAME: (i32 [[U:%.*]])
; IS__TUNIT_OPM-NEXT: entry:
; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]])
; IS__TUNIT_OPM-NEXT: ret i32 [[CALL]]
;
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; 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]]) [[ATTR1:#.*]], [[RNG3:!range !.*]]
; IS__TUNIT_NPM-NEXT: ret i32 [[CALL]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test4-g2
; IS__CGSCC____-SAME: (i32 [[U:%.*]])
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]])
; IS__CGSCC____-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), [[RNG3:!range !.*]]
; 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), [[RNG4:!range !.*]]
; 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) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@phi
; IS__TUNIT____-SAME: (i32 [[ARG:%.*]])
; IS__TUNIT____-NEXT: bb:
; IS__TUNIT____-NEXT: [[TMP:%.*]] = icmp sgt i32 [[ARG]], 5
; IS__TUNIT____-NEXT: br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]]
; IS__TUNIT____: bb1:
; IS__TUNIT____-NEXT: br label [[BB3:%.*]]
; IS__TUNIT____: bb2:
; IS__TUNIT____-NEXT: br label [[BB3]]
; IS__TUNIT____: bb3:
; IS__TUNIT____-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[ARG]], 10
; IS__TUNIT____-NEXT: br i1 [[TMP4]], label [[BB5:%.*]], label [[BB7:%.*]]
; IS__TUNIT____: bb5:
; IS__TUNIT____-NEXT: br label [[BB9:%.*]]
; IS__TUNIT____: bb7:
; IS__TUNIT____-NEXT: br label [[BB9]]
; IS__TUNIT____: bb9:
; IS__TUNIT____-NEXT: br label [[BB12:%.*]]
; IS__TUNIT____: bb11:
; IS__TUNIT____-NEXT: unreachable
; IS__TUNIT____: bb12:
; IS__TUNIT____-NEXT: br label [[BB13:%.*]]
; IS__TUNIT____: bb13:
; IS__TUNIT____-NEXT: ret i1 false
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@phi
; IS__CGSCC____-SAME: (i32 [[ARG:%.*]])
; IS__CGSCC____-NEXT: bb:
; IS__CGSCC____-NEXT: [[TMP:%.*]] = icmp sgt i32 [[ARG]], 5
; IS__CGSCC____-NEXT: br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]]
; IS__CGSCC____: bb1:
; IS__CGSCC____-NEXT: br label [[BB3:%.*]]
; IS__CGSCC____: bb2:
; IS__CGSCC____-NEXT: br label [[BB3]]
; IS__CGSCC____: bb3:
; IS__CGSCC____-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[ARG]], 10
; IS__CGSCC____-NEXT: br i1 [[TMP4]], label [[BB5:%.*]], label [[BB7:%.*]]
; IS__CGSCC____: bb5:
; IS__CGSCC____-NEXT: br label [[BB9:%.*]]
; IS__CGSCC____: bb7:
; IS__CGSCC____-NEXT: br label [[BB9]]
; IS__CGSCC____: bb9:
; IS__CGSCC____-NEXT: br label [[BB12:%.*]]
; IS__CGSCC____: bb11:
; IS__CGSCC____-NEXT: unreachable
; IS__CGSCC____: bb12:
; IS__CGSCC____-NEXT: br label [[BB13:%.*]]
; IS__CGSCC____: bb13:
; IS__CGSCC____-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 {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@select
; IS__TUNIT____-SAME: (i32 [[A:%.*]]) local_unnamed_addr
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: ret i1 false
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@select
; IS__CGSCC____-SAME: (i32 [[A:%.*]]) local_unnamed_addr
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-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 {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@select_zext
; IS__TUNIT____-SAME: (i32 [[A:%.*]]) local_unnamed_addr
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: ret i32 0
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@select_zext
; IS__CGSCC____-SAME: (i32 [[A:%.*]]) local_unnamed_addr
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-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 {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int
; IS__TUNIT____-SAME: (i32 [[A:%.*]]) local_unnamed_addr
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[I2P:%.*]] = inttoptr i1 false to i1*
; IS__TUNIT____-NEXT: [[BC:%.*]] = bitcast i1* [[I2P]] to i32*
; IS__TUNIT____-NEXT: [[P2I:%.*]] = ptrtoint i32* [[BC]] to i64
; IS__TUNIT____-NEXT: ret i64 [[P2I]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int
; IS__CGSCC____-SAME: (i32 [[A:%.*]]) local_unnamed_addr
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[I2P:%.*]] = inttoptr i1 false to i1*
; IS__CGSCC____-NEXT: [[BC:%.*]] = bitcast i1* [[I2P]] to i32*
; IS__CGSCC____-NEXT: [[P2I:%.*]] = ptrtoint i32* [[BC]] to i64
; IS__CGSCC____-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) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@f_fcmp
; IS__TUNIT____-SAME: (float [[A:%.*]], float [[B:%.*]])
; IS__TUNIT____-NEXT: [[R:%.*]] = fcmp uge float [[A]], [[B]]
; IS__TUNIT____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
; IS__TUNIT____-NEXT: ret i1 [[S]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@f_fcmp
; IS__CGSCC____-SAME: (float [[A:%.*]], float [[B:%.*]])
; IS__CGSCC____-NEXT: [[R:%.*]] = fcmp uge float [[A]], [[B]]
; IS__CGSCC____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
; IS__CGSCC____-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) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@d_fcmp
; IS__TUNIT____-SAME: (double [[A:%.*]], double [[B:%.*]])
; IS__TUNIT____-NEXT: [[R:%.*]] = fcmp oeq double [[A]], [[B]]
; IS__TUNIT____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
; IS__TUNIT____-NEXT: ret i1 [[S]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@d_fcmp
; IS__CGSCC____-SAME: (double [[A:%.*]], double [[B:%.*]])
; IS__CGSCC____-NEXT: [[R:%.*]] = fcmp oeq double [[A]], [[B]]
; IS__CGSCC____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
; IS__CGSCC____-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) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@dp_icmp
; IS__TUNIT____-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]])
; IS__TUNIT____-NEXT: [[R:%.*]] = icmp sge double* [[A]], [[B]]
; IS__TUNIT____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
; IS__TUNIT____-NEXT: ret i1 [[S]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@dp_icmp
; IS__CGSCC____-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]])
; IS__CGSCC____-NEXT: [[R:%.*]] = icmp sge double* [[A]], [[B]]
; IS__CGSCC____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
; IS__CGSCC____-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) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@ip_icmp
; IS__TUNIT____-SAME: (i8* nofree readnone [[A:%.*]], i8* nofree readnone [[B:%.*]])
; IS__TUNIT____-NEXT: [[R:%.*]] = icmp ult i8* [[A]], [[B]]
; IS__TUNIT____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
; IS__TUNIT____-NEXT: ret i1 [[S]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@ip_icmp
; IS__CGSCC____-SAME: (i8* nofree readnone [[A:%.*]], i8* nofree readnone [[B:%.*]])
; IS__CGSCC____-NEXT: [[R:%.*]] = icmp ult i8* [[A]], [[B]]
; IS__CGSCC____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
; IS__CGSCC____-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) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@fcmp_caller
; IS__TUNIT____-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:%.*]])
; IS__TUNIT____-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]])
; IS__TUNIT____-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]])
; IS__TUNIT____-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]])
; IS__TUNIT____-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]])
; IS__TUNIT____-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]]
; IS__TUNIT____-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]]
; IS__TUNIT____-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]]
; IS__TUNIT____-NEXT: ret i1 [[O3]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@fcmp_caller
; IS__CGSCC____-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:%.*]])
; IS__CGSCC____-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]])
; IS__CGSCC____-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]])
; IS__CGSCC____-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]])
; IS__CGSCC____-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]])
; IS__CGSCC____-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]]
; IS__CGSCC____-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]]
; IS__CGSCC____-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]]
; IS__CGSCC____-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() {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_two()
; IS__TUNIT____-NEXT: ret i8 2
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_two()
; IS__CGSCC____-NEXT: ret i8 2
;
ret i8 2
}
define i8 @ret_undef() {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_undef()
; IS__TUNIT____-NEXT: ret i8 undef
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_undef()
; IS__CGSCC____-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() {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@undef_collapse_1()
; IS__TUNIT____-NEXT: ret i8 0
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@undef_collapse_1()
; IS__CGSCC____-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() {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@undef_collapse_2()
; IS__TUNIT____-NEXT: ret i8 0
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@undef_collapse_2()
; IS__CGSCC____-NEXT: ret i8 0
;
%c = call i8 @ret_two()
%s = shl i8 undef, %c
ret i8 %s
}
define i8 @undef_collapse_caller() {
;
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@undef_collapse_caller()
; IS__TUNIT____-NEXT: ret i8 0
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; 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) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@ret1or2
; IS__TUNIT____-SAME: (i1 [[C:%.*]])
; IS__TUNIT____-NEXT: [[S:%.*]] = select i1 [[C]], i32 1, i32 2
; IS__TUNIT____-NEXT: ret i32 [[S]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@ret1or2
; IS__CGSCC____-SAME: (i1 [[C:%.*]])
; IS__CGSCC____-NEXT: [[S:%.*]] = select i1 [[C]], i32 1, i32 2
; IS__CGSCC____-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____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@callee_range_1
; IS__TUNIT____-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]])
; IS__TUNIT____-NEXT: ret i1 true
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; 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: Function Attrs: nofree nosync nounwind readnone willreturn
; 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]]) [[ATTR2:#.*]], [[RNG4:!range !.*]]
; IS__TUNIT_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) [[ATTR2]], [[RNG4]]
; 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: Function Attrs: nofree nosync nounwind readnone willreturn
; 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]]) [[ATTR1]], [[RNG5:!range !.*]]
; IS__TUNIT_NPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) [[ATTR1]], [[RNG5]]
; 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____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; 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() {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@ret100()
; IS__TUNIT____-NEXT: ret i32 100
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@ret100()
; IS__CGSCC____-NEXT: ret i32 100
;
ret i32 100
}
define i1 @ctx_adjustment(i32 %V) {
;
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@ctx_adjustment
; IS__TUNIT_OPM-SAME: (i32 [[V:%.*]])
; IS__TUNIT_OPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100
; IS__TUNIT_OPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
; IS__TUNIT_OPM: if.true:
; IS__TUNIT_OPM-NEXT: br label [[END:%.*]]
; IS__TUNIT_OPM: if.false:
; IS__TUNIT_OPM-NEXT: br label [[END]]
; IS__TUNIT_OPM: end:
; IS__TUNIT_OPM-NEXT: [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ 100, [[IF_FALSE]] ]
; IS__TUNIT_OPM-NEXT: [[C2:%.*]] = icmp sge i32 [[PHI]], 100
; IS__TUNIT_OPM-NEXT: ret i1 [[C2]]
;
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@ctx_adjustment
; IS__TUNIT_NPM-SAME: (i32 [[V:%.*]])
; IS__TUNIT_NPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100
; IS__TUNIT_NPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
; IS__TUNIT_NPM: if.true:
; IS__TUNIT_NPM-NEXT: br label [[END:%.*]]
; IS__TUNIT_NPM: if.false:
; IS__TUNIT_NPM-NEXT: br label [[END]]
; IS__TUNIT_NPM: end:
; IS__TUNIT_NPM-NEXT: ret i1 true
;
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ctx_adjustment
; IS__CGSCC_OPM-SAME: (i32 [[V:%.*]])
; IS__CGSCC_OPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100
; IS__CGSCC_OPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
; IS__CGSCC_OPM: if.true:
; IS__CGSCC_OPM-NEXT: br label [[END:%.*]]
; IS__CGSCC_OPM: if.false:
; IS__CGSCC_OPM-NEXT: br label [[END]]
; IS__CGSCC_OPM: end:
; IS__CGSCC_OPM-NEXT: [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ 100, [[IF_FALSE]] ]
; IS__CGSCC_OPM-NEXT: [[C2:%.*]] = icmp sge i32 [[PHI]], 100
; IS__CGSCC_OPM-NEXT: ret i1 [[C2]]
;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ctx_adjustment
; IS__CGSCC_NPM-SAME: (i32 [[V:%.*]])
; IS__CGSCC_NPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100
; IS__CGSCC_NPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
; IS__CGSCC_NPM: if.true:
; IS__CGSCC_NPM-NEXT: br label [[END:%.*]]
; IS__CGSCC_NPM: if.false:
; IS__CGSCC_NPM-NEXT: br label [[END]]
; IS__CGSCC_NPM: end:
; IS__CGSCC_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
}
define i32 @func(i1 %c) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@func
; IS__TUNIT____-SAME: (i1 [[C:%.*]])
; IS__TUNIT____-NEXT: [[RET:%.*]] = select i1 [[C]], i32 0, i32 1
; IS__TUNIT____-NEXT: ret i32 [[RET]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@func
; IS__CGSCC____-SAME: (i1 [[C:%.*]])
; IS__CGSCC____-NEXT: [[RET:%.*]] = select i1 [[C]], i32 0, i32 1
; IS__CGSCC____-NEXT: ret i32 [[RET]]
;
%ret = select i1 %c, i32 0, i32 1
ret i32 %ret
}
define i32 @simplify_callsite_argument(i1 %d) {
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@simplify_callsite_argument
; IS__TUNIT_OPM-SAME: (i1 [[D:%.*]])
; IS__TUNIT_OPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__TUNIT_OPM: t:
; IS__TUNIT_OPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 [[C]]) [[ATTR2]], [[RNG3]]
; IS__TUNIT_OPM-NEXT: ret i32 [[RET1]]
; IS__TUNIT_OPM: f:
; IS__TUNIT_OPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 false) [[ATTR2]], [[RNG3]]
; IS__TUNIT_OPM-NEXT: ret i32 [[RET2]]
;
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@simplify_callsite_argument
; IS__TUNIT_NPM-SAME: (i1 [[D:%.*]])
; IS__TUNIT_NPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__TUNIT_NPM: t:
; IS__TUNIT_NPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 true) [[ATTR1]], [[RNG4]]
; IS__TUNIT_NPM-NEXT: ret i32 [[RET1]]
; IS__TUNIT_NPM: f:
; IS__TUNIT_NPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 false) [[ATTR1]], [[RNG4]]
; IS__TUNIT_NPM-NEXT: ret i32 [[RET2]]
;
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@simplify_callsite_argument
; IS__CGSCC_OPM-SAME: (i1 [[D:%.*]])
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__CGSCC_OPM: t:
; IS__CGSCC_OPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 [[C]])
; IS__CGSCC_OPM-NEXT: ret i32 [[RET1]]
; IS__CGSCC_OPM: f:
; IS__CGSCC_OPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 false)
; IS__CGSCC_OPM-NEXT: ret i32 [[RET2]]
;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@simplify_callsite_argument
; IS__CGSCC_NPM-SAME: (i1 [[D:%.*]])
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__CGSCC_NPM: t:
; IS__CGSCC_NPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 true)
; IS__CGSCC_NPM-NEXT: ret i32 [[RET1]]
; IS__CGSCC_NPM: f:
; IS__CGSCC_NPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 false)
; IS__CGSCC_NPM-NEXT: ret i32 [[RET2]]
;
%c = select i1 %d, i1 true, i1 false
br i1 %c, label %t, label %f
t:
%ret1 = call i32 @func(i1 %c)
ret i32 %ret1
f:
%ret2 = call i32 @func(i1 false)
ret i32 %ret2
}
define internal i32 @less_than_65536(i32 %arg) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@less_than_65536
; IS__TUNIT____-SAME: (i32 [[ARG:%.*]])
; IS__TUNIT____-NEXT: [[SHRINKED:%.*]] = udiv i32 [[ARG]], 65536
; IS__TUNIT____-NEXT: ret i32 [[SHRINKED]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@less_than_65536
; IS__CGSCC____-SAME: (i32 [[ARG:%.*]])
; IS__CGSCC____-NEXT: [[SHRINKED:%.*]] = udiv i32 [[ARG]], 65536
; IS__CGSCC____-NEXT: ret i32 [[SHRINKED]]
;
%shrinked = udiv i32 %arg, 65536
ret i32 %shrinked
}
define internal i1 @is_less_than_65536(i32 %arg) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@is_less_than_65536
; IS__TUNIT____-SAME: (i32 [[ARG:%.*]])
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp ult i32 [[ARG]], 65536
; IS__TUNIT____-NEXT: ret i1 [[CMP]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_65536
; IS__CGSCC____-SAME: (i32 [[ARG:%.*]])
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp ult i32 [[ARG]], 65536
; IS__CGSCC____-NEXT: ret i1 [[CMP]]
;
%cmp = icmp ult i32 %arg, 65536
ret i1 %cmp
}
; FIXME: returned value can be simplified to i1 true
define i1 @check_divided_range(i32 %arg) {
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@check_divided_range
; IS__TUNIT_OPM-SAME: (i32 [[ARG:%.*]])
; IS__TUNIT_OPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 0)
; IS__TUNIT_OPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]])
; IS__TUNIT_OPM-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]])
; IS__TUNIT_OPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]])
; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
; IS__TUNIT_OPM-NEXT: ret i1 [[RET]]
;
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@check_divided_range
; IS__TUNIT_NPM-SAME: (i32 [[ARG:%.*]])
; IS__TUNIT_NPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 0) [[ATTR1]], [[RNG6:!range !.*]]
; IS__TUNIT_NPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) [[ATTR1]], [[RNG6]]
; IS__TUNIT_NPM-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]])
; IS__TUNIT_NPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]])
; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
; IS__TUNIT_NPM-NEXT: ret i1 [[RET]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@check_divided_range
; IS__CGSCC____-SAME: (i32 [[ARG:%.*]])
; IS__CGSCC____-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 0)
; IS__CGSCC____-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]])
; IS__CGSCC____-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]])
; IS__CGSCC____-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]])
; IS__CGSCC____-NEXT: [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
; IS__CGSCC____-NEXT: ret i1 [[RET]]
;
%csret1 = call i32 @less_than_65536(i32 0)
%csret2 = call i32 @less_than_65536(i32 %arg)
%true1 = call i1 @is_less_than_65536(i32 %csret1)
%true2 = call i1 @is_less_than_65536(i32 %csret2)
%ret = and i1 %true1, %true2
ret i1 %ret
}
define internal i32 @cast_and_return(i1 %c) {
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@cast_and_return
; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]])
; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = zext i1 [[C]] to i32
; IS__TUNIT_OPM-NEXT: ret i32 [[RET]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@cast_and_return
; IS__CGSCC____-SAME: (i1 [[C:%.*]])
; IS__CGSCC____-NEXT: [[RET:%.*]] = zext i1 [[C]] to i32
; IS__CGSCC____-NEXT: ret i32 [[RET]]
;
%ret = zext i1 %c to i32
ret i32 %ret
}
define internal i1 @is_less_than_3(i32 %c) {
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@is_less_than_3
; IS__TUNIT_OPM-SAME: (i32 [[C:%.*]])
; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 3
; IS__TUNIT_OPM-NEXT: ret i1 [[CMP]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_3
; IS__CGSCC____-SAME: (i32 [[C:%.*]])
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 3
; IS__CGSCC____-NEXT: ret i1 [[CMP]]
;
%cmp = icmp slt i32 %c, 3
ret i1 %cmp
}
; FIXME: returned value can be simplified to i1 true
define i1 @check_casted_range(i1 %c) {
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@check_casted_range
; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]])
; IS__TUNIT_OPM-NEXT: [[CSRET1:%.*]] = call i32 @cast_and_return(i1 true)
; IS__TUNIT_OPM-NEXT: [[CSRET2:%.*]] = call i32 @cast_and_return(i1 [[C]])
; IS__TUNIT_OPM-NEXT: [[ADD:%.*]] = add i32 [[CSRET1]], [[CSRET2]]
; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = call i1 @is_less_than_3(i32 [[ADD]])
; IS__TUNIT_OPM-NEXT: ret i1 [[RET]]
;
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@check_casted_range
; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]])
; IS__TUNIT_NPM-NEXT: ret i1 true
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@check_casted_range
; IS__CGSCC____-SAME: (i1 [[C:%.*]])
; IS__CGSCC____-NEXT: [[CSRET1:%.*]] = call i32 @cast_and_return(i1 true)
; IS__CGSCC____-NEXT: [[CSRET2:%.*]] = call i32 @cast_and_return(i1 [[C]])
; IS__CGSCC____-NEXT: [[ADD:%.*]] = add i32 [[CSRET1]], [[CSRET2]]
; IS__CGSCC____-NEXT: [[RET:%.*]] = call i1 @is_less_than_3(i32 [[ADD]])
; IS__CGSCC____-NEXT: ret i1 [[RET]]
;
%csret1 = call i32 @cast_and_return(i1 true)
%csret2 = call i32 @cast_and_return(i1 %c)
%add = add i32 %csret1, %csret2
%ret = call i1 @is_less_than_3(i32 %add)
ret i1 %ret
}
define internal i32 @less_than_100_1(i32 %c) {
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@less_than_100_1
; IS__CGSCC____-SAME: (i32 [[C:%.*]])
; IS__CGSCC____-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [
; IS__CGSCC____-NEXT: i32 0, label [[ONZERO:%.*]]
; IS__CGSCC____-NEXT: i32 1, label [[ONONE:%.*]]
; IS__CGSCC____-NEXT: i32 2, label [[ONTWO:%.*]]
; IS__CGSCC____-NEXT: i32 3, label [[ONTHREE:%.*]]
; IS__CGSCC____-NEXT: i32 4, label [[ONFOUR:%.*]]
; IS__CGSCC____-NEXT: i32 5, label [[ONFIVE:%.*]]
; IS__CGSCC____-NEXT: i32 6, label [[ONSIX:%.*]]
; IS__CGSCC____-NEXT: ]
; IS__CGSCC____: onzero:
; IS__CGSCC____-NEXT: ret i32 0
; IS__CGSCC____: onone:
; IS__CGSCC____-NEXT: ret i32 1
; IS__CGSCC____: ontwo:
; IS__CGSCC____-NEXT: ret i32 2
; IS__CGSCC____: onthree:
; IS__CGSCC____-NEXT: ret i32 3
; IS__CGSCC____: onfour:
; IS__CGSCC____-NEXT: ret i32 4
; IS__CGSCC____: onfive:
; IS__CGSCC____-NEXT: ret i32 5
; IS__CGSCC____: onsix:
; IS__CGSCC____-NEXT: ret i32 6
; IS__CGSCC____: otherwise:
; IS__CGSCC____-NEXT: ret i32 99
;
switch i32 %c, label %otherwise [ i32 0, label %onzero
i32 1, label %onone
i32 2, label %ontwo
i32 3, label %onthree
i32 4, label %onfour
i32 5, label %onfive
i32 6, label %onsix]
onzero:
ret i32 0
onone:
ret i32 1
ontwo:
ret i32 2
onthree:
ret i32 3
onfour:
ret i32 4
onfive:
ret i32 5
onsix:
ret i32 6
otherwise:
ret i32 99
}
define internal i1 @is_less_than_100_1(i32 %c) {
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_100_1
; IS__CGSCC____-SAME: (i32 [[C:%.*]])
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 100
; IS__CGSCC____-NEXT: ret i1 [[CMP]]
;
%cmp = icmp slt i32 %c, 100
ret i1 %cmp
}
define i1 @propagate_range1(i32 %c){
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@propagate_range1
; IS__TUNIT____-SAME: (i32 [[C:%.*]])
; IS__TUNIT____-NEXT: ret i1 true
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@propagate_range1
; IS__CGSCC____-SAME: (i32 [[C:%.*]])
; IS__CGSCC____-NEXT: [[CSRET:%.*]] = call i32 @less_than_100_1(i32 [[C]])
; IS__CGSCC____-NEXT: [[TRUE:%.*]] = call i1 @is_less_than_100_1(i32 [[CSRET]])
; IS__CGSCC____-NEXT: ret i1 [[TRUE]]
;
%csret = call i32 @less_than_100_1(i32 %c)
%true = call i1 @is_less_than_100_1(i32 %csret)
ret i1 %true
}
define internal i32 @less_than_100_2(i32 %c) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@less_than_100_2
; IS__TUNIT____-SAME: (i32 [[C:%.*]])
; IS__TUNIT____-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [
; IS__TUNIT____-NEXT: i32 0, label [[ONZERO:%.*]]
; IS__TUNIT____-NEXT: i32 1, label [[ONONE:%.*]]
; IS__TUNIT____-NEXT: i32 2, label [[ONTWO:%.*]]
; IS__TUNIT____-NEXT: i32 3, label [[ONTHREE:%.*]]
; IS__TUNIT____-NEXT: i32 4, label [[ONFOUR:%.*]]
; IS__TUNIT____-NEXT: i32 5, label [[ONFIVE:%.*]]
; IS__TUNIT____-NEXT: i32 6, label [[ONSIX:%.*]]
; IS__TUNIT____-NEXT: ]
; IS__TUNIT____: onzero:
; IS__TUNIT____-NEXT: ret i32 0
; IS__TUNIT____: onone:
; IS__TUNIT____-NEXT: ret i32 1
; IS__TUNIT____: ontwo:
; IS__TUNIT____-NEXT: ret i32 2
; IS__TUNIT____: onthree:
; IS__TUNIT____-NEXT: ret i32 3
; IS__TUNIT____: onfour:
; IS__TUNIT____-NEXT: ret i32 4
; IS__TUNIT____: onfive:
; IS__TUNIT____-NEXT: ret i32 5
; IS__TUNIT____: onsix:
; IS__TUNIT____-NEXT: ret i32 6
; IS__TUNIT____: otherwise:
; IS__TUNIT____-NEXT: ret i32 99
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@less_than_100_2
; IS__CGSCC____-SAME: (i32 [[C:%.*]])
; IS__CGSCC____-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [
; IS__CGSCC____-NEXT: i32 0, label [[ONZERO:%.*]]
; IS__CGSCC____-NEXT: i32 1, label [[ONONE:%.*]]
; IS__CGSCC____-NEXT: i32 2, label [[ONTWO:%.*]]
; IS__CGSCC____-NEXT: i32 3, label [[ONTHREE:%.*]]
; IS__CGSCC____-NEXT: i32 4, label [[ONFOUR:%.*]]
; IS__CGSCC____-NEXT: i32 5, label [[ONFIVE:%.*]]
; IS__CGSCC____-NEXT: i32 6, label [[ONSIX:%.*]]
; IS__CGSCC____-NEXT: ]
; IS__CGSCC____: onzero:
; IS__CGSCC____-NEXT: ret i32 0
; IS__CGSCC____: onone:
; IS__CGSCC____-NEXT: ret i32 1
; IS__CGSCC____: ontwo:
; IS__CGSCC____-NEXT: ret i32 2
; IS__CGSCC____: onthree:
; IS__CGSCC____-NEXT: ret i32 3
; IS__CGSCC____: onfour:
; IS__CGSCC____-NEXT: ret i32 4
; IS__CGSCC____: onfive:
; IS__CGSCC____-NEXT: ret i32 5
; IS__CGSCC____: onsix:
; IS__CGSCC____-NEXT: ret i32 6
; IS__CGSCC____: otherwise:
; IS__CGSCC____-NEXT: ret i32 99
;
switch i32 %c, label %otherwise [ i32 0, label %onzero
i32 1, label %onone
i32 2, label %ontwo
i32 3, label %onthree
i32 4, label %onfour
i32 5, label %onfive
i32 6, label %onsix]
onzero:
ret i32 0
onone:
ret i32 1
ontwo:
ret i32 2
onthree:
ret i32 3
onfour:
ret i32 4
onfive:
ret i32 5
onsix:
ret i32 6
otherwise:
ret i32 99
}
define internal i1 @is_less_than_100_2(i32 %c) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@is_less_than_100_2
; IS__TUNIT____-SAME: (i32 [[C:%.*]])
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 100
; IS__TUNIT____-NEXT: ret i1 [[CMP]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_100_2
; IS__CGSCC____-SAME: (i32 [[C:%.*]])
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 100
; IS__CGSCC____-NEXT: ret i1 [[CMP]]
;
%cmp = icmp slt i32 %c, 100
ret i1 %cmp
}
; FIXME: returned value can be simplified to i1 true
define i1 @propagate_range2(i32 %c) {
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@propagate_range2
; IS__TUNIT_OPM-SAME: (i32 [[C:%.*]])
; IS__TUNIT_OPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 0) [[ATTR2]], [[RNG5:!range !.*]]
; IS__TUNIT_OPM-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 [[CSRET1]])
; IS__TUNIT_OPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 [[C]]) [[ATTR2]], [[RNG5]]
; IS__TUNIT_OPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 [[CSRET2]])
; IS__TUNIT_OPM-NEXT: [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
; IS__TUNIT_OPM-NEXT: ret i1 [[TRUE]]
;
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@propagate_range2
; IS__TUNIT_NPM-SAME: (i32 [[C:%.*]])
; IS__TUNIT_NPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 0) [[ATTR1]], [[RNG7:!range !.*]]
; IS__TUNIT_NPM-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 [[CSRET1]])
; IS__TUNIT_NPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 [[C]]) [[ATTR1]], [[RNG7]]
; IS__TUNIT_NPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 [[CSRET2]])
; IS__TUNIT_NPM-NEXT: [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
; IS__TUNIT_NPM-NEXT: ret i1 [[TRUE]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@propagate_range2
; IS__CGSCC____-SAME: (i32 [[C:%.*]])
; IS__CGSCC____-NEXT: [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 0)
; IS__CGSCC____-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 [[CSRET1]])
; IS__CGSCC____-NEXT: [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 [[C]])
; IS__CGSCC____-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 [[CSRET2]])
; IS__CGSCC____-NEXT: [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
; IS__CGSCC____-NEXT: ret i1 [[TRUE]]
;
%csret1 = call i32 @less_than_100_2(i32 0)
%true1 = call i1 @is_less_than_100_2(i32 %csret1)
%csret2 = call i32 @less_than_100_2(i32 %c)
%true2 = call i1 @is_less_than_100_2(i32 %csret2)
%true = and i1 %true1, %true2
ret i1 %true
}
!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: !5 = !{i32 0, i32 100}
; IS__TUNIT_OPM-NOT: !6
; 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: !6 = !{i32 0, i32 65536}
; IS__TUNIT_NPM: !7 = !{i32 0, i32 100}
; IS__TUNIT_NPM-NOT: !8