1820 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals2; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT3; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC4 5; FIXME: CGSCC is not looking at callees and calleers even though it could be allowed.6 7define i32 @test0(ptr %p) {8; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)9; CHECK-LABEL: define {{[^@]+}}@test010; CHECK-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR0:[0-9]+]] {11; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0:![0-9]+]]12; CHECK-NEXT: ret i32 [[A]]13;14 %a = load i32, ptr %p, !range !015 ret i32 %a16}17 18define i32 @test0-range-check(ptr %p) {19; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)20; TUNIT-LABEL: define {{[^@]+}}@test0-range-check21; TUNIT-SAME: (ptr nofree readonly align 4 captures(none) [[P:%.*]]) #[[ATTR0]] {22; TUNIT-NEXT: [[A:%.*]] = tail call range(i32 0, 10) i32 @test0(ptr nofree noundef readonly align 4 captures(none) [[P]]) #[[ATTR3:[0-9]+]]23; TUNIT-NEXT: ret i32 [[A]]24;25; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)26; CGSCC-LABEL: define {{[^@]+}}@test0-range-check27; CGSCC-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR1:[0-9]+]] {28; CGSCC-NEXT: [[A:%.*]] = tail call i32 @test0(ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P]]) #[[ATTR5:[0-9]+]]29; CGSCC-NEXT: ret i32 [[A]]30;31 %a = tail call i32 @test0(ptr %p)32 ret i32 %a33}34 35define i32 @test0-range-check-smaller-current-range-attr(ptr %p) {36; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)37; TUNIT-LABEL: define {{[^@]+}}@test0-range-check-smaller-current-range-attr38; TUNIT-SAME: (ptr nofree readonly align 4 captures(none) [[P:%.*]]) #[[ATTR0]] {39; TUNIT-NEXT: [[A:%.*]] = tail call range(i32 2, 5) i32 @test0(ptr nofree noundef readonly align 4 captures(none) [[P]]) #[[ATTR3]]40; TUNIT-NEXT: ret i32 [[A]]41;42; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)43; CGSCC-LABEL: define {{[^@]+}}@test0-range-check-smaller-current-range-attr44; CGSCC-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR1]] {45; CGSCC-NEXT: [[A:%.*]] = tail call range(i32 2, 5) i32 @test0(ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P]]) #[[ATTR5]]46; CGSCC-NEXT: ret i32 [[A]]47;48 %a = tail call range(i32 2, 5) i32 @test0(ptr %p)49 ret i32 %a50}51 52define i32 @test0-range-check-larger-current-range-attr(ptr %p) {53; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)54; TUNIT-LABEL: define {{[^@]+}}@test0-range-check-larger-current-range-attr55; TUNIT-SAME: (ptr nofree readonly align 4 captures(none) [[P:%.*]]) #[[ATTR0]] {56; TUNIT-NEXT: [[A:%.*]] = tail call range(i32 0, 10) i32 @test0(ptr nofree noundef readonly align 4 captures(none) [[P]]) #[[ATTR3]]57; TUNIT-NEXT: ret i32 [[A]]58;59; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)60; CGSCC-LABEL: define {{[^@]+}}@test0-range-check-larger-current-range-attr61; CGSCC-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR1]] {62; CGSCC-NEXT: [[A:%.*]] = tail call range(i32 0, 100) i32 @test0(ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P]]) #[[ATTR5]]63; CGSCC-NEXT: ret i32 [[A]]64;65 %a = tail call range(i32 0, 100) i32 @test0(ptr %p)66 ret i32 %a67}68 69declare void @use3-dummy(i1, i1, i1)70define void @use3(i1, i1, i1) {71; CHECK-LABEL: define {{[^@]+}}@use372; CHECK-SAME: (i1 [[TMP0:%.*]], i1 [[TMP1:%.*]], i1 [[TMP2:%.*]]) {73; CHECK-NEXT: tail call void @use3-dummy(i1 [[TMP0]], i1 [[TMP1]], i1 [[TMP2]])74; CHECK-NEXT: ret void75;76 tail call void @use3-dummy(i1 %0, i1 %1, i1 %2)77 ret void78}79 80; TEST0 icmp test81define void @test0-icmp-check(ptr %p){82 ; ret = [0, 10)83; TUNIT-LABEL: define {{[^@]+}}@test0-icmp-check84; TUNIT-SAME: (ptr nofree readonly align 4 captures(none) [[P:%.*]]) {85; TUNIT-NEXT: [[RET:%.*]] = tail call range(i32 0, 10) i32 @test0(ptr nofree noundef readonly align 4 captures(none) [[P]]) #[[ATTR3]]86; TUNIT-NEXT: [[CMP_EQ_1:%.*]] = icmp eq i32 [[RET]], 1087; TUNIT-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 988; TUNIT-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 889; TUNIT-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 190; TUNIT-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 091; TUNIT-NEXT: [[CMP_EQ_6:%.*]] = icmp eq i32 [[RET]], -192; TUNIT-NEXT: tail call void @use3(i1 [[CMP_EQ_1]], i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]])93; TUNIT-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 [[CMP_EQ_6]])94; TUNIT-NEXT: [[CMP_NE_1:%.*]] = icmp ne i32 [[RET]], 1095; TUNIT-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 996; TUNIT-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 897; TUNIT-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 198; TUNIT-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 099; TUNIT-NEXT: [[CMP_NE_6:%.*]] = icmp ne i32 [[RET]], -1100; TUNIT-NEXT: tail call void @use3(i1 [[CMP_NE_1]], i1 [[CMP_NE_2]], i1 [[CMP_NE_3]])101; TUNIT-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 [[CMP_NE_6]])102; TUNIT-NEXT: [[CMP_UGT_1:%.*]] = icmp ugt i32 [[RET]], 10103; TUNIT-NEXT: [[CMP_UGT_2:%.*]] = icmp ugt i32 [[RET]], 9104; TUNIT-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8105; TUNIT-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1106; TUNIT-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0107; TUNIT-NEXT: tail call void @use3(i1 [[CMP_UGT_1]], i1 [[CMP_UGT_2]], i1 [[CMP_UGT_3]])108; TUNIT-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 noundef false)109; TUNIT-NEXT: [[CMP_UGE_1:%.*]] = icmp uge i32 [[RET]], 10110; TUNIT-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9111; TUNIT-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8112; TUNIT-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1113; TUNIT-NEXT: [[CMP_UGE_6:%.*]] = icmp uge i32 [[RET]], -1114; TUNIT-NEXT: tail call void @use3(i1 [[CMP_UGE_1]], i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]])115; TUNIT-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 noundef true, i1 [[CMP_UGE_6]])116; TUNIT-NEXT: [[CMP_SGT_1:%.*]] = icmp sgt i32 [[RET]], 10117; TUNIT-NEXT: [[CMP_SGT_2:%.*]] = icmp sgt i32 [[RET]], 9118; TUNIT-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8119; TUNIT-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1120; TUNIT-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0121; TUNIT-NEXT: [[CMP_SGT_6:%.*]] = icmp sgt i32 [[RET]], -1122; TUNIT-NEXT: tail call void @use3(i1 [[CMP_SGT_1]], i1 [[CMP_SGT_2]], i1 [[CMP_SGT_3]])123; TUNIT-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 [[CMP_SGT_6]])124; TUNIT-NEXT: [[CMP_GTE_1:%.*]] = icmp sge i32 [[RET]], 10125; TUNIT-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9126; TUNIT-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8127; TUNIT-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1128; TUNIT-NEXT: [[CMP_GTE_5:%.*]] = icmp sge i32 [[RET]], 0129; TUNIT-NEXT: [[CMP_GTE_6:%.*]] = icmp sge i32 [[RET]], -1130; TUNIT-NEXT: tail call void @use3(i1 [[CMP_GTE_1]], i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]])131; TUNIT-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 [[CMP_GTE_5]], i1 [[CMP_GTE_6]])132; TUNIT-NEXT: [[CMP_SLT_1:%.*]] = icmp slt i32 [[RET]], 10133; TUNIT-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9134; TUNIT-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8135; TUNIT-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1136; TUNIT-NEXT: [[CMP_SLT_5:%.*]] = icmp slt i32 [[RET]], 0137; TUNIT-NEXT: [[CMP_SLT_6:%.*]] = icmp slt i32 [[RET]], -1138; TUNIT-NEXT: tail call void @use3(i1 [[CMP_SLT_1]], i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]])139; TUNIT-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 [[CMP_SLT_5]], i1 [[CMP_SLT_6]])140; TUNIT-NEXT: [[CMP_LTE_1:%.*]] = icmp sle i32 [[RET]], 10141; TUNIT-NEXT: [[CMP_LTE_2:%.*]] = icmp sle i32 [[RET]], 9142; TUNIT-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8143; TUNIT-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1144; TUNIT-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0145; TUNIT-NEXT: [[CMP_LTE_6:%.*]] = icmp sle i32 [[RET]], -1146; TUNIT-NEXT: tail call void @use3(i1 [[CMP_LTE_1]], i1 [[CMP_LTE_2]], i1 [[CMP_LTE_3]])147; TUNIT-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 [[CMP_LTE_6]])148; TUNIT-NEXT: ret void149;150; CGSCC-LABEL: define {{[^@]+}}@test0-icmp-check151; CGSCC-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) {152; CGSCC-NEXT: [[RET:%.*]] = tail call i32 @test0(ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P]]) #[[ATTR5]]153; CGSCC-NEXT: [[CMP_EQ_1:%.*]] = icmp eq i32 [[RET]], 10154; CGSCC-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9155; CGSCC-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8156; CGSCC-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1157; CGSCC-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0158; CGSCC-NEXT: [[CMP_EQ_6:%.*]] = icmp eq i32 [[RET]], -1159; CGSCC-NEXT: tail call void @use3(i1 [[CMP_EQ_1]], i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]])160; CGSCC-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 [[CMP_EQ_6]])161; CGSCC-NEXT: [[CMP_NE_1:%.*]] = icmp ne i32 [[RET]], 10162; CGSCC-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9163; CGSCC-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8164; CGSCC-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1165; CGSCC-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0166; CGSCC-NEXT: [[CMP_NE_6:%.*]] = icmp ne i32 [[RET]], -1167; CGSCC-NEXT: tail call void @use3(i1 [[CMP_NE_1]], i1 [[CMP_NE_2]], i1 [[CMP_NE_3]])168; CGSCC-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 [[CMP_NE_6]])169; CGSCC-NEXT: [[CMP_UGT_1:%.*]] = icmp ugt i32 [[RET]], 10170; CGSCC-NEXT: [[CMP_UGT_2:%.*]] = icmp ugt i32 [[RET]], 9171; CGSCC-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8172; CGSCC-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1173; CGSCC-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0174; CGSCC-NEXT: tail call void @use3(i1 [[CMP_UGT_1]], i1 [[CMP_UGT_2]], i1 [[CMP_UGT_3]])175; CGSCC-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 noundef false)176; CGSCC-NEXT: [[CMP_UGE_1:%.*]] = icmp uge i32 [[RET]], 10177; CGSCC-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9178; CGSCC-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8179; CGSCC-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1180; CGSCC-NEXT: [[CMP_UGE_6:%.*]] = icmp uge i32 [[RET]], -1181; CGSCC-NEXT: tail call void @use3(i1 [[CMP_UGE_1]], i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]])182; CGSCC-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 noundef true, i1 [[CMP_UGE_6]])183; CGSCC-NEXT: [[CMP_SGT_1:%.*]] = icmp sgt i32 [[RET]], 10184; CGSCC-NEXT: [[CMP_SGT_2:%.*]] = icmp sgt i32 [[RET]], 9185; CGSCC-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8186; CGSCC-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1187; CGSCC-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0188; CGSCC-NEXT: [[CMP_SGT_6:%.*]] = icmp sgt i32 [[RET]], -1189; CGSCC-NEXT: tail call void @use3(i1 [[CMP_SGT_1]], i1 [[CMP_SGT_2]], i1 [[CMP_SGT_3]])190; CGSCC-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 [[CMP_SGT_6]])191; CGSCC-NEXT: [[CMP_GTE_1:%.*]] = icmp sge i32 [[RET]], 10192; CGSCC-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9193; CGSCC-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8194; CGSCC-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1195; CGSCC-NEXT: [[CMP_GTE_5:%.*]] = icmp sge i32 [[RET]], 0196; CGSCC-NEXT: [[CMP_GTE_6:%.*]] = icmp sge i32 [[RET]], -1197; CGSCC-NEXT: tail call void @use3(i1 [[CMP_GTE_1]], i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]])198; CGSCC-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 [[CMP_GTE_5]], i1 [[CMP_GTE_6]])199; CGSCC-NEXT: [[CMP_SLT_1:%.*]] = icmp slt i32 [[RET]], 10200; CGSCC-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9201; CGSCC-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8202; CGSCC-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1203; CGSCC-NEXT: [[CMP_SLT_5:%.*]] = icmp slt i32 [[RET]], 0204; CGSCC-NEXT: [[CMP_SLT_6:%.*]] = icmp slt i32 [[RET]], -1205; CGSCC-NEXT: tail call void @use3(i1 [[CMP_SLT_1]], i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]])206; CGSCC-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 [[CMP_SLT_5]], i1 [[CMP_SLT_6]])207; CGSCC-NEXT: [[CMP_LTE_1:%.*]] = icmp sle i32 [[RET]], 10208; CGSCC-NEXT: [[CMP_LTE_2:%.*]] = icmp sle i32 [[RET]], 9209; CGSCC-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8210; CGSCC-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1211; CGSCC-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0212; CGSCC-NEXT: [[CMP_LTE_6:%.*]] = icmp sle i32 [[RET]], -1213; CGSCC-NEXT: tail call void @use3(i1 [[CMP_LTE_1]], i1 [[CMP_LTE_2]], i1 [[CMP_LTE_3]])214; CGSCC-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 [[CMP_LTE_6]])215; CGSCC-NEXT: ret void216;217 %ret = tail call i32 @test0(ptr %p)218 219 ; ret = [0, 10), eq220 %cmp-eq-1 = icmp eq i32 %ret, 10221 %cmp-eq-2 = icmp eq i32 %ret, 9222 %cmp-eq-3 = icmp eq i32 %ret, 8223 %cmp-eq-4 = icmp eq i32 %ret, 1224 %cmp-eq-5 = icmp eq i32 %ret, 0225 %cmp-eq-6 = icmp eq i32 %ret, -1226 tail call void @use3(i1 %cmp-eq-1, i1 %cmp-eq-2, i1 %cmp-eq-3)227 tail call void @use3(i1 %cmp-eq-4, i1 %cmp-eq-5, i1 %cmp-eq-6)228 229 ; ret = [0, 10), ne230 %cmp-ne-1 = icmp ne i32 %ret, 10231 %cmp-ne-2 = icmp ne i32 %ret, 9232 %cmp-ne-3 = icmp ne i32 %ret, 8233 %cmp-ne-4 = icmp ne i32 %ret, 1234 %cmp-ne-5 = icmp ne i32 %ret, 0235 %cmp-ne-6 = icmp ne i32 %ret, -1236 tail call void @use3(i1 %cmp-ne-1, i1 %cmp-ne-2, i1 %cmp-ne-3)237 tail call void @use3(i1 %cmp-ne-4, i1 %cmp-ne-5, i1 %cmp-ne-6)238 239 ; ret = [0, 10), ugt240 %cmp-ugt-1 = icmp ugt i32 %ret, 10241 %cmp-ugt-2 = icmp ugt i32 %ret, 9242 %cmp-ugt-3 = icmp ugt i32 %ret, 8243 %cmp-ugt-4 = icmp ugt i32 %ret, 1244 %cmp-ugt-5 = icmp ugt i32 %ret, 0245 %cmp-ugt-6 = icmp ugt i32 %ret, -1246 tail call void @use3(i1 %cmp-ugt-1, i1 %cmp-ugt-2, i1 %cmp-ugt-3)247 tail call void @use3(i1 %cmp-ugt-4, i1 %cmp-ugt-5, i1 %cmp-ugt-6)248 249 ; ret = [0, 10), uge250 %cmp-uge-1 = icmp uge i32 %ret, 10251 %cmp-uge-2 = icmp uge i32 %ret, 9252 %cmp-uge-3 = icmp uge i32 %ret, 8253 %cmp-uge-4 = icmp uge i32 %ret, 1254 %cmp-uge-5 = icmp uge i32 %ret, 0255 %cmp-uge-6 = icmp uge i32 %ret, -1256 tail call void @use3(i1 %cmp-uge-1, i1 %cmp-uge-2, i1 %cmp-uge-3)257 tail call void @use3(i1 %cmp-uge-4, i1 %cmp-uge-5, i1 %cmp-uge-6)258 259 ; ret = [0, 10), sgt260 %cmp-sgt-1 = icmp sgt i32 %ret, 10261 %cmp-sgt-2 = icmp sgt i32 %ret, 9262 %cmp-sgt-3 = icmp sgt i32 %ret, 8263 %cmp-sgt-4 = icmp sgt i32 %ret, 1264 %cmp-sgt-5 = icmp sgt i32 %ret, 0265 %cmp-sgt-6 = icmp sgt i32 %ret, -1266 tail call void @use3(i1 %cmp-sgt-1, i1 %cmp-sgt-2, i1 %cmp-sgt-3)267 tail call void @use3(i1 %cmp-sgt-4, i1 %cmp-sgt-5, i1 %cmp-sgt-6)268 269 ; ret = [0, 10), sge270 %cmp-gte-1 = icmp sge i32 %ret, 10271 %cmp-gte-2 = icmp sge i32 %ret, 9272 %cmp-gte-3 = icmp sge i32 %ret, 8273 %cmp-gte-4 = icmp sge i32 %ret, 1274 %cmp-gte-5 = icmp sge i32 %ret, 0275 %cmp-gte-6 = icmp sge i32 %ret, -1276 tail call void @use3(i1 %cmp-gte-1, i1 %cmp-gte-2, i1 %cmp-gte-3)277 tail call void @use3(i1 %cmp-gte-4, i1 %cmp-gte-5, i1 %cmp-gte-6)278 279 ; ret = [0, 10), slt280 %cmp-slt-1 = icmp slt i32 %ret, 10281 %cmp-slt-2 = icmp slt i32 %ret, 9282 %cmp-slt-3 = icmp slt i32 %ret, 8283 %cmp-slt-4 = icmp slt i32 %ret, 1284 %cmp-slt-5 = icmp slt i32 %ret, 0285 %cmp-slt-6 = icmp slt i32 %ret, -1286 tail call void @use3(i1 %cmp-slt-1, i1 %cmp-slt-2, i1 %cmp-slt-3)287 tail call void @use3(i1 %cmp-slt-4, i1 %cmp-slt-5, i1 %cmp-slt-6)288 289 ; ret = [0, 10), sle290 %cmp-lte-1 = icmp sle i32 %ret, 10291 %cmp-lte-2 = icmp sle i32 %ret, 9292 %cmp-lte-3 = icmp sle i32 %ret, 8293 %cmp-lte-4 = icmp sle i32 %ret, 1294 %cmp-lte-5 = icmp sle i32 %ret, 0295 %cmp-lte-6 = icmp sle i32 %ret, -1296 tail call void @use3(i1 %cmp-lte-1, i1 %cmp-lte-2, i1 %cmp-lte-3)297 tail call void @use3(i1 %cmp-lte-4, i1 %cmp-lte-5, i1 %cmp-lte-6)298 299 ret void300}301define i32 @test1(ptr %p) {302; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)303; CHECK-LABEL: define {{[^@]+}}@test1304; CHECK-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR0]] {305; CHECK-NEXT: [[LOAD_10_100:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG1:![0-9]+]]306; CHECK-NEXT: [[ADD_10_THEN_20_110:%.*]] = add i32 [[LOAD_10_100]], 10307; CHECK-NEXT: [[MUL_10_THEN_200_1091:%.*]] = mul i32 [[ADD_10_THEN_20_110]], 10308; CHECK-NEXT: ret i32 [[MUL_10_THEN_200_1091]]309;310 %load-10-100 = load i32, ptr %p, !range !1311 %add-10-then-20-110 = add i32 %load-10-100, 10312 %mul-10-then-200-1091 = mul i32 %add-10-then-20-110, 10313 ret i32 %mul-10-then-200-1091314}315 316define i1 @test1-check(ptr %p) {317;318; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)319; TUNIT-LABEL: define {{[^@]+}}@test1-check320; TUNIT-SAME: (ptr nofree readonly align 4 captures(none) [[P:%.*]]) #[[ATTR0]] {321; TUNIT-NEXT: [[RES:%.*]] = tail call range(i32 200, 1091) i32 @test1(ptr nofree noundef readonly align 4 captures(none) [[P]]) #[[ATTR3]]322; TUNIT-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500323; TUNIT-NEXT: ret i1 [[CMP]]324;325; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)326; CGSCC-LABEL: define {{[^@]+}}@test1-check327; CGSCC-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR1]] {328; CGSCC-NEXT: [[RES:%.*]] = tail call i32 @test1(ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P]]) #[[ATTR5]]329; CGSCC-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500330; CGSCC-NEXT: ret i1 [[CMP]]331;332 %res = tail call i32 @test1(ptr %p)333 %cmp = icmp eq i32 %res, 500334 ret i1 %cmp335}336 337; TEST2338; int test2(int *p) { return *p == 0 ? 4 : 3; }339; int test2_check(int *p) {340; int call = test2(p);341; if (call == 5) {342; // dead block343; return 2;344; } else {345; return 3;346; }347; }348 349define i32 @test2(ptr %p) {350; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)351; CHECK-LABEL: define {{[^@]+}}@test2352; CHECK-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR0]] {353; CHECK-NEXT: entry:354; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[P]], align 4355; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0356; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 4, i32 3357; CHECK-NEXT: ret i32 [[COND]]358;359entry:360 %0 = load i32, ptr %p, align 4361 %tobool = icmp eq i32 %0, 0362 %cond = select i1 %tobool, i32 4, i32 3363 ret i32 %cond364}365 366define i32 @test2_check(ptr %p) {367; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)368; TUNIT-LABEL: define {{[^@]+}}@test2_check369; TUNIT-SAME: (ptr nofree readnone align 4 captures(none) [[P:%.*]]) #[[ATTR1:[0-9]+]] {370; TUNIT-NEXT: entry:371; TUNIT-NEXT: br label [[IF_THEN:%.*]]372; TUNIT: if.then:373; TUNIT-NEXT: br label [[RETURN:%.*]]374; TUNIT: if.end:375; TUNIT-NEXT: unreachable376; TUNIT: return:377; TUNIT-NEXT: ret i32 2378;379; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)380; CGSCC-LABEL: define {{[^@]+}}@test2_check381; CGSCC-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR1]] {382; CGSCC-NEXT: entry:383; CGSCC-NEXT: [[CALL:%.*]] = tail call i32 @test2(ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P]]) #[[ATTR5]]384; CGSCC-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 5385; CGSCC-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]386; CGSCC: if.then:387; CGSCC-NEXT: br label [[RETURN:%.*]]388; CGSCC: if.end:389; CGSCC-NEXT: br label [[RETURN]]390; CGSCC: return:391; CGSCC-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 2, [[IF_THEN]] ], [ 3, [[IF_END]] ]392; CGSCC-NEXT: ret i32 [[RETVAL_0]]393;394entry:395 %call = tail call i32 @test2(ptr %p)396 %cmp = icmp slt i32 %call, 5397 br i1 %cmp, label %if.then, label %if.end398 399if.then: ; preds = %entry400 br label %return401 402if.end: ; preds = %entry403 br label %return404 405return: ; preds = %if.end, %if.then406 %retval.0 = phi i32 [ 2, %if.then ], [ 3, %if.end ]407 ret i32 %retval.0408}409 410; TEST 3 SECV test411 412; void unkown();413; int r1(unsigned int u){414; int sum = 0;415; for(int i = 0; i<100;i++){416; sum += i;417; }418; // sum = 50 * 49 / 2419; if(sum > 10000){420; // dead block421; return 20;422; }else {423; return 10;424; }425; }426; void f1(int u){427; if(r1(u) > 15){428; // deadblock429; unkown();430; }else {431; return;432; }433; }434 435declare dso_local void @unkown()436 437define internal i32 @r1(i32) local_unnamed_addr {438; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)439; TUNIT-LABEL: define {{[^@]+}}@r1440; TUNIT-SAME: () local_unnamed_addr #[[ATTR1]] {441; TUNIT-NEXT: br label [[TMP4:%.*]]442; TUNIT: 1:443; TUNIT-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP7:%.*]], 10000444; TUNIT-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[F:%.*]]445; TUNIT: 3:446; TUNIT-NEXT: ret i32 20447; TUNIT: f:448; TUNIT-NEXT: ret i32 10449; TUNIT: 4:450; TUNIT-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[TMP8:%.*]], [[TMP4]] ]451; TUNIT-NEXT: [[TMP6:%.*]] = phi i32 [ 0, [[TMP0]] ], [ [[TMP7]], [[TMP4]] ]452; TUNIT-NEXT: [[TMP7]] = add nuw nsw i32 [[TMP5]], [[TMP6]]453; TUNIT-NEXT: [[TMP8]] = add nuw nsw i32 [[TMP5]], 1454; TUNIT-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 100455; TUNIT-NEXT: br i1 [[TMP9]], label [[TMP1:%.*]], label [[TMP4]]456;457; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)458; CGSCC-LABEL: define {{[^@]+}}@r1459; CGSCC-SAME: () local_unnamed_addr #[[ATTR2:[0-9]+]] {460; CGSCC-NEXT: br label [[TMP4:%.*]]461; CGSCC: 1:462; CGSCC-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP7:%.*]], 10000463; CGSCC-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[F:%.*]]464; CGSCC: 3:465; CGSCC-NEXT: ret i32 20466; CGSCC: f:467; CGSCC-NEXT: ret i32 10468; CGSCC: 4:469; CGSCC-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[TMP8:%.*]], [[TMP4]] ]470; CGSCC-NEXT: [[TMP6:%.*]] = phi i32 [ 0, [[TMP0]] ], [ [[TMP7]], [[TMP4]] ]471; CGSCC-NEXT: [[TMP7]] = add nuw nsw i32 [[TMP5]], [[TMP6]]472; CGSCC-NEXT: [[TMP8]] = add nuw nsw i32 [[TMP5]], 1473; CGSCC-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 100474; CGSCC-NEXT: br i1 [[TMP9]], label [[TMP1:%.*]], label [[TMP4]]475;476 br label %5477 4782: ; preds = %5479 %3 = icmp sgt i32 %8, 10000480 br i1 %3, label %4, label %f4814:482 ret i32 20483f:484 ret i32 104855: ; preds = %5, %1486 %6 = phi i32 [ 0, %1 ], [ %9, %5 ]487 %7 = phi i32 [ 0, %1 ], [ %8, %5 ]488 %8 = add nuw nsw i32 %6, %7489 %9 = add nuw nsw i32 %6, 1490 %10 = icmp eq i32 %9, 100491 br i1 %10, label %2, label %5492}493 494define void @f1(i32){495; TUNIT-LABEL: define {{[^@]+}}@f1496; TUNIT-SAME: (i32 [[TMP0:%.*]]) {497; TUNIT-NEXT: [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR4:[0-9]+]]498; TUNIT-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15499; TUNIT-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]500; TUNIT: 4:501; TUNIT-NEXT: tail call void @unkown()502; TUNIT-NEXT: br label [[TMP5]]503; TUNIT: 5:504; TUNIT-NEXT: ret void505;506; CGSCC-LABEL: define {{[^@]+}}@f1507; CGSCC-SAME: (i32 [[TMP0:%.*]]) {508; CGSCC-NEXT: [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR6:[0-9]+]]509; CGSCC-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15510; CGSCC-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]511; CGSCC: 4:512; CGSCC-NEXT: tail call void @unkown()513; CGSCC-NEXT: br label [[TMP5]]514; CGSCC: 5:515; CGSCC-NEXT: ret void516;517 %2 = tail call i32 @r1(i32 %0)518 %3 = icmp sgt i32 %2, 15519 br i1 %3, label %4, label %5520 5214: ; preds = %1522 tail call void @unkown()523 br label %5524 5255: ; preds = %1, %4526 ret void527}528 529; TEST4 LVI test530 531; f1532; int test4-f1(int u){533; if(u>=0) {534; return u;535; }else{536; return 0;537; }538; }539define dso_local i32 @test4-f1(i32 %u) {540; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)541; TUNIT-LABEL: define {{[^@]+}}@test4-f1542; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] {543; TUNIT-NEXT: entry:544; TUNIT-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1545; TUNIT-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]546; TUNIT: if.then:547; TUNIT-NEXT: br label [[RETURN]]548; TUNIT: return:549; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]550; TUNIT-NEXT: ret i32 [[RETVAL_0]]551;552; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)553; CGSCC-LABEL: define {{[^@]+}}@test4-f1554; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR2]] {555; CGSCC-NEXT: entry:556; CGSCC-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1557; CGSCC-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]558; CGSCC: if.then:559; CGSCC-NEXT: br label [[RETURN]]560; CGSCC: return:561; CGSCC-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]562; CGSCC-NEXT: ret i32 [[RETVAL_0]]563;564; FIXME: RETVAL_0 >= 0565entry:566 %cmp = icmp sgt i32 %u, -1567 br i1 %cmp, label %if.then, label %return568 569if.then: ; preds = %entry570 br label %return571 572return: ; preds = %entry, %if.then573 %retval.0 = phi i32 [ %u, %if.then ], [ 0, %entry ]574 ret i32 %retval.0575}576 577 578define dso_local i32 @test4-g1(i32 %u) {579; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)580; TUNIT-LABEL: define {{[^@]+}}@test4-g1581; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] {582; TUNIT-NEXT: entry:583; TUNIT-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR4]]584; TUNIT-NEXT: ret i32 [[CALL]]585;586; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)587; CGSCC-LABEL: define {{[^@]+}}@test4-g1588; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR3:[0-9]+]] {589; CGSCC-NEXT: entry:590; CGSCC-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR7:[0-9]+]]591; CGSCC-NEXT: ret i32 [[CALL]]592;593; FIXME: %call should have range [0, inf]594 595entry:596 %call = tail call i32 @test4-f1(i32 %u)597 ret i32 %call598}599 600; f2601; int test4-f1(int u){602; if(u>-1) {603; return u+1;604; }else{605; return 1;606; }607; }608define dso_local i32 @test4-f2(i32 %u) {609; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)610; TUNIT-LABEL: define {{[^@]+}}@test4-f2611; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] {612; TUNIT-NEXT: entry:613; TUNIT-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1614; TUNIT-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]615; TUNIT: if.then:616; TUNIT-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[U]], 1617; TUNIT-NEXT: br label [[RETURN:%.*]]618; TUNIT: if.else:619; TUNIT-NEXT: br label [[RETURN]]620; TUNIT: return:621; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ]622; TUNIT-NEXT: ret i32 [[RETVAL_0]]623;624; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)625; CGSCC-LABEL: define {{[^@]+}}@test4-f2626; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR2]] {627; CGSCC-NEXT: entry:628; CGSCC-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1629; CGSCC-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]630; CGSCC: if.then:631; CGSCC-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[U]], 1632; CGSCC-NEXT: br label [[RETURN:%.*]]633; CGSCC: if.else:634; CGSCC-NEXT: br label [[RETURN]]635; CGSCC: return:636; CGSCC-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ]637; CGSCC-NEXT: ret i32 [[RETVAL_0]]638;639entry:640 %cmp = icmp sgt i32 %u, -1641 br i1 %cmp, label %if.then, label %if.else642 643if.then: ; preds = %entry644 %add = add nuw nsw i32 %u, 1645 br label %return646 647if.else: ; preds = %entry648 br label %return649 650return: ; preds = %if.else, %if.then651 %retval.0 = phi i32 [ %add, %if.then ], [ 1, %if.else ]652 ret i32 %retval.0653}654 655 656define dso_local i32 @test4-g2(i32 %u) {657; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)658; TUNIT-LABEL: define {{[^@]+}}@test4-g2659; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] {660; TUNIT-NEXT: entry:661; TUNIT-NEXT: [[CALL:%.*]] = tail call range(i32 1, -2147483648) i32 @test4-f2(i32 [[U]]) #[[ATTR4]]662; TUNIT-NEXT: ret i32 [[CALL]]663;664; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)665; CGSCC-LABEL: define {{[^@]+}}@test4-g2666; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR3]] {667; CGSCC-NEXT: entry:668; CGSCC-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR7]]669; CGSCC-NEXT: ret i32 [[CALL]]670;671entry:672 %call = tail call i32 @test4-f2(i32 %u)673 ret i32 %call674}675 676define dso_local i32 @test-5() {677; TUNIT-LABEL: define {{[^@]+}}@test-5() {678; TUNIT-NEXT: entry:679; TUNIT-NEXT: [[CALL:%.*]] = call i32 @rec(i32 noundef 0)680; TUNIT-NEXT: ret i32 [[CALL]]681;682; CGSCC-LABEL: define {{[^@]+}}@test-5() {683; CGSCC-NEXT: entry:684; CGSCC-NEXT: [[CALL:%.*]] = call noundef i32 @rec(i32 noundef 0)685; CGSCC-NEXT: ret i32 [[CALL]]686;687entry:688 %call = call i32 @rec(i32 0)689 ret i32 %call690}691define internal i32 @rec(i32 %depth) {692; CHECK-LABEL: define {{[^@]+}}@rec693; CHECK-SAME: (i32 [[DEPTH:%.*]]) {694; CHECK-NEXT: entry:695; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo(i32 [[DEPTH]])696; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[CALL]], 0697; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]698; CHECK: if.then:699; CHECK-NEXT: br label [[RETURN:%.*]]700; CHECK: if.end:701; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[DEPTH]], 10702; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_END3:%.*]]703; CHECK: if.then1:704; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[DEPTH]], 1705; CHECK-NEXT: [[CALL2:%.*]] = call i32 @rec(i32 [[ADD]])706; CHECK-NEXT: br label [[IF_END3]]707; CHECK: if.end3:708; CHECK-NEXT: br label [[RETURN]]709; CHECK: return:710; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 0, [[IF_THEN]] ], [ 1, [[IF_END3]] ]711; CHECK-NEXT: ret i32 [[RETVAL_0]]712;713entry:714 %call = call i32 @foo(i32 %depth)715 %tobool = icmp ne i32 %call, 0716 br i1 %tobool, label %if.then, label %if.end717 718if.then: ; preds = %entry719 br label %return720 721if.end: ; preds = %entry722 %cmp = icmp slt i32 %depth, 10723 br i1 %cmp, label %if.then1, label %if.end3724 725if.then1: ; preds = %if.end726 %add = add nsw i32 %depth, 1727 %call2 = call i32 @rec(i32 %add)728 br label %if.end3729 730if.end3: ; preds = %if.then1, %if.end731 br label %return732 733return: ; preds = %if.end3, %if.then734 %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.end3 ]735 ret i32 %retval.0736}737declare dso_local i32 @foo(i32)738 739 740; Examples taken from https://llvm.discourse.group/t/impossible-condition-optimization/461/1741;742; The important part is that we return a constant (false)743;744; {745 746; FIXME: All but the return is not needed anymore747define dso_local zeroext i1 @phi(i32 %arg) {748; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)749; TUNIT-LABEL: define {{[^@]+}}@phi750; TUNIT-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] {751; TUNIT-NEXT: bb:752; TUNIT-NEXT: [[TMP:%.*]] = icmp sgt i32 [[ARG]], 5753; TUNIT-NEXT: br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]]754; TUNIT: bb1:755; TUNIT-NEXT: br label [[BB3:%.*]]756; TUNIT: bb2:757; TUNIT-NEXT: br label [[BB3]]758; TUNIT: bb3:759; TUNIT-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[ARG]], 10760; TUNIT-NEXT: br i1 [[TMP4]], label [[BB5:%.*]], label [[BB7:%.*]]761; TUNIT: bb5:762; TUNIT-NEXT: br label [[BB9:%.*]]763; TUNIT: bb7:764; TUNIT-NEXT: br label [[BB9]]765; TUNIT: bb9:766; TUNIT-NEXT: br label [[BB12:%.*]]767; TUNIT: bb11:768; TUNIT-NEXT: unreachable769; TUNIT: bb12:770; TUNIT-NEXT: br label [[BB13:%.*]]771; TUNIT: bb13:772; TUNIT-NEXT: ret i1 false773;774; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)775; CGSCC-LABEL: define {{[^@]+}}@phi776; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR2]] {777; CGSCC-NEXT: bb:778; CGSCC-NEXT: [[TMP:%.*]] = icmp sgt i32 [[ARG]], 5779; CGSCC-NEXT: br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]]780; CGSCC: bb1:781; CGSCC-NEXT: br label [[BB3:%.*]]782; CGSCC: bb2:783; CGSCC-NEXT: br label [[BB3]]784; CGSCC: bb3:785; CGSCC-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[ARG]], 10786; CGSCC-NEXT: br i1 [[TMP4]], label [[BB5:%.*]], label [[BB7:%.*]]787; CGSCC: bb5:788; CGSCC-NEXT: br label [[BB9:%.*]]789; CGSCC: bb7:790; CGSCC-NEXT: br label [[BB9]]791; CGSCC: bb9:792; CGSCC-NEXT: br label [[BB12:%.*]]793; CGSCC: bb11:794; CGSCC-NEXT: unreachable795; CGSCC: bb12:796; CGSCC-NEXT: br label [[BB13:%.*]]797; CGSCC: bb13:798; CGSCC-NEXT: ret i1 false799;800bb:801 %tmp = icmp sgt i32 %arg, 5802 br i1 %tmp, label %bb1, label %bb2803 804bb1: ; preds = %bb805 br label %bb3806 807bb2: ; preds = %bb808 br label %bb3809 810bb3: ; preds = %bb2, %bb1811 %.02 = phi i32 [ 1, %bb1 ], [ 2, %bb2 ]812 %tmp4 = icmp sgt i32 %arg, 10813 br i1 %tmp4, label %bb5, label %bb7814 815bb5: ; preds = %bb3816 %tmp6 = add nsw i32 %.02, 1817 br label %bb9818 819bb7: ; preds = %bb3820 %tmp8 = add nsw i32 %.02, 2821 br label %bb9822 823bb9: ; preds = %bb7, %bb5824 %.01 = phi i32 [ %tmp6, %bb5 ], [ %tmp8, %bb7 ]825 %tmp10 = icmp eq i32 %.01, 5826 br i1 %tmp10, label %bb11, label %bb12827 828bb11: ; preds = %bb9829 br label %bb13830 831bb12: ; preds = %bb9832 br label %bb13833 834bb13: ; preds = %bb12, %bb11835 %.0 = phi i1 [ true, %bb11 ], [ false, %bb12 ]836 ret i1 %.0837}838 839define dso_local i1 @select(i32 %a) local_unnamed_addr #0 {840; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)841; TUNIT-LABEL: define {{[^@]+}}@select842; TUNIT-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] {843; TUNIT-NEXT: entry:844; TUNIT-NEXT: ret i1 false845;846; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)847; CGSCC-LABEL: define {{[^@]+}}@select848; CGSCC-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR2]] {849; CGSCC-NEXT: entry:850; CGSCC-NEXT: ret i1 false851;852entry:853 %cmp = icmp sgt i32 %a, 5854 %. = select i1 %cmp, i32 1, i32 2855 %cmp1 = icmp sgt i32 %a, 10856 %y.0.v = select i1 %cmp1, i32 1, i32 2857 %y.0 = add nuw nsw i32 %., %y.0.v858 %cmp6 = icmp eq i32 %y.0, 5859 ret i1 %cmp6860}861 862define dso_local i32 @select_zext(i32 %a) local_unnamed_addr #0 {863; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)864; TUNIT-LABEL: define {{[^@]+}}@select_zext865; TUNIT-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] {866; TUNIT-NEXT: entry:867; TUNIT-NEXT: ret i32 0868;869; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)870; CGSCC-LABEL: define {{[^@]+}}@select_zext871; CGSCC-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR2]] {872; CGSCC-NEXT: entry:873; CGSCC-NEXT: ret i32 0874;875entry:876 %cmp = icmp sgt i32 %a, 5877 %. = select i1 %cmp, i32 1, i32 2878 %cmp1 = icmp sgt i32 %a, 10879 %y.0.v = select i1 %cmp1, i32 1, i32 2880 %y.0 = add nuw nsw i32 %., %y.0.v881 %cmp6 = icmp eq i32 %y.0, 5882 %.13 = zext i1 %cmp6 to i32883 ret i32 %.13884}885 886define dso_local i64 @select_int2ptr_bitcast_ptr2int(i32 %a) local_unnamed_addr #0 {887; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)888; TUNIT-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int889; TUNIT-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] {890; TUNIT-NEXT: entry:891; TUNIT-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 5892; TUNIT-NEXT: [[DOT:%.*]] = select i1 [[CMP]], i32 1, i32 2893; TUNIT-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A]], 10894; TUNIT-NEXT: [[Y_0_V:%.*]] = select i1 [[CMP1]], i32 1, i32 2895; TUNIT-NEXT: [[Y_0:%.*]] = add nuw nsw i32 [[DOT]], [[Y_0_V]]896; TUNIT-NEXT: [[CMP6:%.*]] = icmp eq i32 [[Y_0]], 5897; TUNIT-NEXT: [[I2P:%.*]] = inttoptr i1 [[CMP6]] to ptr898; TUNIT-NEXT: [[P2I:%.*]] = ptrtoint ptr [[I2P]] to i64899; TUNIT-NEXT: ret i64 [[P2I]]900;901; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)902; CGSCC-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int903; CGSCC-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR2]] {904; CGSCC-NEXT: entry:905; CGSCC-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 5906; CGSCC-NEXT: [[DOT:%.*]] = select i1 [[CMP]], i32 1, i32 2907; CGSCC-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A]], 10908; CGSCC-NEXT: [[Y_0_V:%.*]] = select i1 [[CMP1]], i32 1, i32 2909; CGSCC-NEXT: [[Y_0:%.*]] = add nuw nsw i32 [[DOT]], [[Y_0_V]]910; CGSCC-NEXT: [[CMP6:%.*]] = icmp eq i32 [[Y_0]], 5911; CGSCC-NEXT: [[I2P:%.*]] = inttoptr i1 [[CMP6]] to ptr912; CGSCC-NEXT: [[P2I:%.*]] = ptrtoint ptr [[I2P]] to i64913; CGSCC-NEXT: ret i64 [[P2I]]914;915entry:916 %cmp = icmp sgt i32 %a, 5917 %. = select i1 %cmp, i32 1, i32 2918 %cmp1 = icmp sgt i32 %a, 10919 %y.0.v = select i1 %cmp1, i32 1, i32 2920 %y.0 = add nuw nsw i32 %., %y.0.v921 %cmp6 = icmp eq i32 %y.0, 5922 %i2p = inttoptr i1 %cmp6 to ptr923 %p2i = ptrtoint ptr %i2p to i64924 ret i64 %p2i925}926 927; }928 929define i1 @f_fcmp(float %a, float %b) {930; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)931; TUNIT-LABEL: define {{[^@]+}}@f_fcmp932; TUNIT-SAME: (float [[A:%.*]], float [[B:%.*]]) #[[ATTR1]] {933; TUNIT-NEXT: [[R:%.*]] = fcmp uge float [[A]], [[B]]934; TUNIT-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false935; TUNIT-NEXT: ret i1 [[S]]936;937; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)938; CGSCC-LABEL: define {{[^@]+}}@f_fcmp939; CGSCC-SAME: (float [[A:%.*]], float [[B:%.*]]) #[[ATTR2]] {940; CGSCC-NEXT: [[R:%.*]] = fcmp uge float [[A]], [[B]]941; CGSCC-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false942; CGSCC-NEXT: ret i1 [[S]]943;944 %r = fcmp uge float %a, %b945 %s = select i1 %r, i1 %r, i1 0946 ret i1 %s947}948define i1 @d_fcmp(double %a, double %b) {949; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)950; TUNIT-LABEL: define {{[^@]+}}@d_fcmp951; TUNIT-SAME: (double [[A:%.*]], double [[B:%.*]]) #[[ATTR1]] {952; TUNIT-NEXT: [[R:%.*]] = fcmp oeq double [[A]], [[B]]953; TUNIT-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false954; TUNIT-NEXT: ret i1 [[S]]955;956; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)957; CGSCC-LABEL: define {{[^@]+}}@d_fcmp958; CGSCC-SAME: (double [[A:%.*]], double [[B:%.*]]) #[[ATTR2]] {959; CGSCC-NEXT: [[R:%.*]] = fcmp oeq double [[A]], [[B]]960; CGSCC-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false961; CGSCC-NEXT: ret i1 [[S]]962;963 %r = fcmp oeq double %a, %b964 %s = select i1 %r, i1 %r, i1 0965 ret i1 %s966}967define i1 @dp_icmp(ptr %a, ptr %b) {968; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)969; TUNIT-LABEL: define {{[^@]+}}@dp_icmp970; TUNIT-SAME: (ptr nofree readnone [[A:%.*]], ptr nofree readnone [[B:%.*]]) #[[ATTR1]] {971; TUNIT-NEXT: [[R:%.*]] = icmp sge ptr [[A]], [[B]]972; TUNIT-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false973; TUNIT-NEXT: ret i1 [[S]]974;975; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)976; CGSCC-LABEL: define {{[^@]+}}@dp_icmp977; CGSCC-SAME: (ptr nofree readnone [[A:%.*]], ptr nofree readnone [[B:%.*]]) #[[ATTR2]] {978; CGSCC-NEXT: [[R:%.*]] = icmp sge ptr [[A]], [[B]]979; CGSCC-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false980; CGSCC-NEXT: ret i1 [[S]]981;982 %r = icmp sge ptr %a, %b983 %s = select i1 %r, i1 %r, i1 0984 ret i1 %s985}986define i1 @ip_icmp(ptr %a, ptr %b) {987; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)988; TUNIT-LABEL: define {{[^@]+}}@ip_icmp989; TUNIT-SAME: (ptr nofree readnone [[A:%.*]], ptr nofree readnone [[B:%.*]]) #[[ATTR1]] {990; TUNIT-NEXT: [[R:%.*]] = icmp ult ptr [[A]], [[B]]991; TUNIT-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false992; TUNIT-NEXT: ret i1 [[S]]993;994; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)995; CGSCC-LABEL: define {{[^@]+}}@ip_icmp996; CGSCC-SAME: (ptr nofree readnone [[A:%.*]], ptr nofree readnone [[B:%.*]]) #[[ATTR2]] {997; CGSCC-NEXT: [[R:%.*]] = icmp ult ptr [[A]], [[B]]998; CGSCC-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false999; CGSCC-NEXT: ret i1 [[S]]1000;1001 %r = icmp ult ptr %a, %b1002 %s = select i1 %r, i1 %r, i1 01003 ret i1 %s1004}1005define i1 @fcmp_caller(float %fa, float %fb, double %da, double %db, ptr %dpa, ptr %dpb, ptr %ipa, ptr %ipb) {1006; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1007; TUNIT-LABEL: define {{[^@]+}}@fcmp_caller1008; TUNIT-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], ptr nofree readnone [[DPA:%.*]], ptr nofree readnone [[DPB:%.*]], ptr nofree readnone [[IPA:%.*]], ptr nofree readnone [[IPB:%.*]]) #[[ATTR1]] {1009; TUNIT-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR4]]1010; TUNIT-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR4]]1011; TUNIT-NEXT: [[R3:%.*]] = call i1 @dp_icmp(ptr noalias nofree readnone [[DPA]], ptr noalias nofree readnone [[DPB]]) #[[ATTR4]]1012; TUNIT-NEXT: [[R4:%.*]] = call i1 @ip_icmp(ptr noalias nofree readnone [[IPA]], ptr noalias nofree readnone [[IPB]]) #[[ATTR4]]1013; TUNIT-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]]1014; TUNIT-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]]1015; TUNIT-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]]1016; TUNIT-NEXT: ret i1 [[O3]]1017;1018; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)1019; CGSCC-LABEL: define {{[^@]+}}@fcmp_caller1020; CGSCC-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], ptr nofree readnone [[DPA:%.*]], ptr nofree readnone [[DPB:%.*]], ptr nofree readnone [[IPA:%.*]], ptr nofree readnone [[IPB:%.*]]) #[[ATTR3]] {1021; CGSCC-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR7]]1022; CGSCC-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR7]]1023; CGSCC-NEXT: [[R3:%.*]] = call i1 @dp_icmp(ptr noalias nofree readnone [[DPA]], ptr noalias nofree readnone [[DPB]]) #[[ATTR7]]1024; CGSCC-NEXT: [[R4:%.*]] = call i1 @ip_icmp(ptr noalias nofree readnone [[IPA]], ptr noalias nofree readnone [[IPB]]) #[[ATTR7]]1025; CGSCC-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]]1026; CGSCC-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]]1027; CGSCC-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]]1028; CGSCC-NEXT: ret i1 [[O3]]1029;1030 %r1 = call i1 @f_fcmp(float %fa, float %fb)1031 %r2 = call i1 @d_fcmp(double %da, double %db)1032 %r3 = call i1 @dp_icmp(ptr %dpa, ptr %dpb)1033 %r4 = call i1 @ip_icmp(ptr %ipa, ptr %ipb)1034 %o1 = or i1 %r1, %r21035 %o2 = or i1 %r3, %r41036 %o3 = or i1 %o1, %o21037 ret i1 %o31038}1039 1040define i8 @ret_two() {1041; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1042; TUNIT-LABEL: define {{[^@]+}}@ret_two1043; TUNIT-SAME: () #[[ATTR1]] {1044; TUNIT-NEXT: ret i8 21045;1046; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1047; CGSCC-LABEL: define {{[^@]+}}@ret_two1048; CGSCC-SAME: () #[[ATTR2]] {1049; CGSCC-NEXT: ret i8 21050;1051 ret i8 21052}1053define i8 @ret_undef() {1054; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1055; TUNIT-LABEL: define {{[^@]+}}@ret_undef1056; TUNIT-SAME: () #[[ATTR1]] {1057; TUNIT-NEXT: ret i8 undef1058;1059; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1060; CGSCC-LABEL: define {{[^@]+}}@ret_undef1061; CGSCC-SAME: () #[[ATTR2]] {1062; CGSCC-NEXT: ret i8 undef1063;1064 ret i8 undef1065}1066 1067; Verify we collapse undef to a value and return something non-undef here.1068define i8 @undef_collapse_1() {1069; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1070; TUNIT-LABEL: define {{[^@]+}}@undef_collapse_11071; TUNIT-SAME: () #[[ATTR1]] {1072; TUNIT-NEXT: ret i8 01073;1074; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)1075; CGSCC-LABEL: define {{[^@]+}}@undef_collapse_11076; CGSCC-SAME: () #[[ATTR3]] {1077; CGSCC-NEXT: [[C:%.*]] = call i8 @ret_undef() #[[ATTR7]]1078; CGSCC-NEXT: [[S:%.*]] = shl i8 [[C]], 21079; CGSCC-NEXT: ret i8 [[S]]1080;1081 %c = call i8 @ret_undef()1082 %s = shl i8 %c, 21083 ret i8 %s1084}1085 1086; Verify we collapse undef to a value and return something non-undef here.1087define i8 @undef_collapse_2() {1088; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1089; TUNIT-LABEL: define {{[^@]+}}@undef_collapse_21090; TUNIT-SAME: () #[[ATTR1]] {1091; TUNIT-NEXT: ret i8 01092;1093; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)1094; CGSCC-LABEL: define {{[^@]+}}@undef_collapse_21095; CGSCC-SAME: () #[[ATTR3]] {1096; CGSCC-NEXT: [[C:%.*]] = call i8 @ret_two() #[[ATTR7]]1097; CGSCC-NEXT: [[S:%.*]] = shl i8 undef, [[C]]1098; CGSCC-NEXT: ret i8 [[S]]1099;1100 %c = call i8 @ret_two()1101 %s = shl i8 undef, %c1102 ret i8 %s1103}1104 1105define i8 @undef_collapse_caller() {1106;1107; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1108; TUNIT-LABEL: define {{[^@]+}}@undef_collapse_caller1109; TUNIT-SAME: () #[[ATTR1]] {1110; TUNIT-NEXT: ret i8 01111;1112; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)1113; CGSCC-LABEL: define {{[^@]+}}@undef_collapse_caller1114; CGSCC-SAME: () #[[ATTR3]] {1115; CGSCC-NEXT: [[C1:%.*]] = call i8 @undef_collapse_1() #[[ATTR7]]1116; CGSCC-NEXT: [[C2:%.*]] = call i8 @undef_collapse_2() #[[ATTR7]]1117; CGSCC-NEXT: [[A:%.*]] = add i8 [[C1]], [[C2]]1118; CGSCC-NEXT: ret i8 [[A]]1119;1120 %c1 = call i8 @undef_collapse_1()1121 %c2 = call i8 @undef_collapse_2()1122 %a = add i8 %c1, %c21123 ret i8 %a1124}1125 1126define i32 @ret1or2(i1 %c) {1127; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1128; TUNIT-LABEL: define {{[^@]+}}@ret1or21129; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {1130; TUNIT-NEXT: [[S:%.*]] = select i1 [[C]], i32 1, i32 21131; TUNIT-NEXT: ret i32 [[S]]1132;1133; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1134; CGSCC-LABEL: define {{[^@]+}}@ret1or21135; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {1136; CGSCC-NEXT: [[S:%.*]] = select i1 [[C]], i32 1, i32 21137; CGSCC-NEXT: ret i32 [[S]]1138;1139 %s = select i1 %c, i32 1, i32 21140 ret i32 %s1141}1142define i1 @callee_range_1(i1 %c1, i1 %c2, i1 %c3) {1143;1144; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1145; TUNIT-LABEL: define {{[^@]+}}@callee_range_11146; TUNIT-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR1]] {1147; TUNIT-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR4]]1148; TUNIT-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR4]]1149; TUNIT-NEXT: [[INDIRECTION:%.*]] = select i1 [[C3]], i32 [[R1]], i32 [[R2]]1150; TUNIT-NEXT: [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]]1151; TUNIT-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 41152; TUNIT-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 21153; TUNIT-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]1154; TUNIT-NEXT: ret i1 [[F]]1155;1156; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)1157; CGSCC-LABEL: define {{[^@]+}}@callee_range_11158; CGSCC-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR3]] {1159; CGSCC-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR7]]1160; CGSCC-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR7]]1161; CGSCC-NEXT: [[INDIRECTION:%.*]] = select i1 [[C3]], i32 [[R1]], i32 [[R2]]1162; CGSCC-NEXT: [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]]1163; CGSCC-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 41164; CGSCC-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 21165; CGSCC-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]1166; CGSCC-NEXT: ret i1 [[F]]1167;1168 %r1 = call i32 @ret1or2(i1 %c1)1169 %r2 = call i32 @ret1or2(i1 %c2)1170 %indirection = select i1 %c3, i32 %r1, i32 %r21171 %a = add i32 %r1, %indirection1172 %i1 = icmp sle i32 %a, 41173 %i2 = icmp sge i32 %a, 21174 %f = and i1 %i1, %i21175 ret i1 %f1176}1177 1178define i1 @callee_range_2(i1 %c1, i1 %c2) {1179;1180; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1181; TUNIT-LABEL: define {{[^@]+}}@callee_range_21182; TUNIT-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR1]] {1183; TUNIT-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR4]]1184; TUNIT-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR4]]1185; TUNIT-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]1186; TUNIT-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 31187; TUNIT-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 21188; TUNIT-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]1189; TUNIT-NEXT: ret i1 [[F]]1190;1191; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)1192; CGSCC-LABEL: define {{[^@]+}}@callee_range_21193; CGSCC-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR3]] {1194; CGSCC-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR7]]1195; CGSCC-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR7]]1196; CGSCC-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]1197; CGSCC-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 31198; CGSCC-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 21199; CGSCC-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]1200; CGSCC-NEXT: ret i1 [[F]]1201;1202 %r1 = call i32 @ret1or2(i1 %c1)1203 %r2 = call i32 @ret1or2(i1 %c2)1204 %a = add i32 %r1, %r21205 %i1 = icmp sle i32 %a, 31206 %i2 = icmp sge i32 %a, 21207 %f = and i1 %i1, %i21208 ret i1 %f1209}1210 1211 1212define i32 @ret100() {1213; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1214; TUNIT-LABEL: define {{[^@]+}}@ret1001215; TUNIT-SAME: () #[[ATTR1]] {1216; TUNIT-NEXT: ret i32 1001217;1218; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1219; CGSCC-LABEL: define {{[^@]+}}@ret1001220; CGSCC-SAME: () #[[ATTR2]] {1221; CGSCC-NEXT: ret i32 1001222;1223 ret i32 1001224}1225 1226define i1 @ctx_adjustment(i32 %V) {1227;1228; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1229; TUNIT-LABEL: define {{[^@]+}}@ctx_adjustment1230; TUNIT-SAME: (i32 [[V:%.*]]) #[[ATTR1]] {1231; TUNIT-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 1001232; TUNIT-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]1233; TUNIT: if.true:1234; TUNIT-NEXT: br label [[END:%.*]]1235; TUNIT: if.false:1236; TUNIT-NEXT: br label [[END]]1237; TUNIT: end:1238; TUNIT-NEXT: [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ 100, [[IF_FALSE]] ]1239; TUNIT-NEXT: [[C2:%.*]] = icmp sge i32 [[PHI]], 1001240; TUNIT-NEXT: ret i1 [[C2]]1241;1242; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)1243; CGSCC-LABEL: define {{[^@]+}}@ctx_adjustment1244; CGSCC-SAME: (i32 [[V:%.*]]) #[[ATTR3]] {1245; CGSCC-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 1001246; CGSCC-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]1247; CGSCC: if.true:1248; CGSCC-NEXT: br label [[END:%.*]]1249; CGSCC: if.false:1250; CGSCC-NEXT: [[CALL:%.*]] = call i32 @ret100() #[[ATTR7]]1251; CGSCC-NEXT: br label [[END]]1252; CGSCC: end:1253; CGSCC-NEXT: [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ [[CALL]], [[IF_FALSE]] ]1254; CGSCC-NEXT: [[C2:%.*]] = icmp sge i32 [[PHI]], 1001255; CGSCC-NEXT: ret i1 [[C2]]1256;1257 %c1 = icmp sge i32 %V, 1001258 br i1 %c1, label %if.true, label %if.false1259if.true:1260 br label %end1261if.false:1262 %call = call i32 @ret100()1263 br label %end1264end:1265 %phi = phi i32 [ %V, %if.true ], [ %call, %if.false ]1266 %c2 = icmp sge i32 %phi, 1001267 ret i1 %c21268}1269 1270 1271define i32 @func(i1 %c) {1272; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1273; TUNIT-LABEL: define {{[^@]+}}@func1274; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {1275; TUNIT-NEXT: [[RET:%.*]] = select i1 [[C]], i32 0, i32 11276; TUNIT-NEXT: ret i32 [[RET]]1277;1278; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1279; CGSCC-LABEL: define {{[^@]+}}@func1280; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {1281; CGSCC-NEXT: [[RET:%.*]] = select i1 [[C]], i32 0, i32 11282; CGSCC-NEXT: ret i32 [[RET]]1283;1284 %ret = select i1 %c, i32 0, i32 11285 ret i32 %ret1286}1287 1288define i32 @simplify_callsite_argument(i1 %d) {1289; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1290; TUNIT-LABEL: define {{[^@]+}}@simplify_callsite_argument1291; TUNIT-SAME: (i1 [[D:%.*]]) #[[ATTR1]] {1292; TUNIT-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false1293; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]1294; TUNIT: t:1295; TUNIT-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef [[C]]) #[[ATTR4]]1296; TUNIT-NEXT: ret i32 [[RET1]]1297; TUNIT: f:1298; TUNIT-NEXT: [[RET2:%.*]] = call i32 @func(i1 noundef false) #[[ATTR4]]1299; TUNIT-NEXT: ret i32 [[RET2]]1300;1301; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)1302; CGSCC-LABEL: define {{[^@]+}}@simplify_callsite_argument1303; CGSCC-SAME: (i1 [[D:%.*]]) #[[ATTR3]] {1304; CGSCC-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false1305; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]1306; CGSCC: t:1307; CGSCC-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef [[C]]) #[[ATTR7]]1308; CGSCC-NEXT: ret i32 [[RET1]]1309; CGSCC: f:1310; CGSCC-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR7]]1311; CGSCC-NEXT: ret i32 [[RET2]]1312;1313 %c = select i1 %d, i1 true, i1 false1314 br i1 %c, label %t, label %f1315t:1316 %ret1 = call i32 @func(i1 %c)1317 ret i32 %ret11318f:1319 %ret2 = call i32 @func(i1 false)1320 ret i32 %ret21321}1322 1323define internal i32 @less_than_65536(i32 %arg) {1324;1325; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1326; CGSCC-LABEL: define {{[^@]+}}@less_than_655361327; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR2]] {1328; CGSCC-NEXT: [[SHRINKED:%.*]] = udiv i32 [[ARG]], 655361329; CGSCC-NEXT: ret i32 [[SHRINKED]]1330;1331 %shrinked = udiv i32 %arg, 655361332 ret i32 %shrinked1333}1334 1335define internal i1 @is_less_than_65536(i32 %arg) {1336; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1337; CGSCC-LABEL: define {{[^@]+}}@is_less_than_655361338; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR2]] {1339; CGSCC-NEXT: [[CMP:%.*]] = icmp ult i32 [[ARG]], 655361340; CGSCC-NEXT: ret i1 [[CMP]]1341;1342 %cmp = icmp ult i32 %arg, 655361343 ret i1 %cmp1344}1345 1346define i1 @check_divided_range(i32 %arg) {1347; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1348; TUNIT-LABEL: define {{[^@]+}}@check_divided_range1349; TUNIT-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] {1350; TUNIT-NEXT: ret i1 true1351;1352; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)1353; CGSCC-LABEL: define {{[^@]+}}@check_divided_range1354; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] {1355; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 noundef 0) #[[ATTR7]]1356; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) #[[ATTR7]]1357; CGSCC-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]]) #[[ATTR7]]1358; CGSCC-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) #[[ATTR7]]1359; CGSCC-NEXT: [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]]1360; CGSCC-NEXT: ret i1 [[RET]]1361;1362 %csret1 = call i32 @less_than_65536(i32 0)1363 %csret2 = call i32 @less_than_65536(i32 %arg)1364 %true1 = call i1 @is_less_than_65536(i32 %csret1)1365 %true2 = call i1 @is_less_than_65536(i32 %csret2)1366 %ret = and i1 %true1, %true21367 ret i1 %ret1368}1369 1370define internal i32 @cast_and_return(i1 %c) {1371;1372; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1373; CGSCC-LABEL: define {{[^@]+}}@cast_and_return1374; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {1375; CGSCC-NEXT: [[RET:%.*]] = zext i1 [[C]] to i321376; CGSCC-NEXT: ret i32 [[RET]]1377;1378 %ret = zext i1 %c to i321379 ret i32 %ret1380}1381 1382define internal i1 @is_less_than_3(i32 %c) {1383; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1384; CGSCC-LABEL: define {{[^@]+}}@is_less_than_31385; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR2]] {1386; CGSCC-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 31387; CGSCC-NEXT: ret i1 [[CMP]]1388;1389 %cmp = icmp slt i32 %c, 31390 ret i1 %cmp1391}1392 1393define i1 @check_casted_range(i1 %c) {1394; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1395; TUNIT-LABEL: define {{[^@]+}}@check_casted_range1396; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {1397; TUNIT-NEXT: ret i1 true1398;1399; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)1400; CGSCC-LABEL: define {{[^@]+}}@check_casted_range1401; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] {1402; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @cast_and_return(i1 noundef true) #[[ATTR7]]1403; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @cast_and_return(i1 [[C]]) #[[ATTR7]]1404; CGSCC-NEXT: [[ADD:%.*]] = add i32 [[CSRET1]], [[CSRET2]]1405; CGSCC-NEXT: [[RET:%.*]] = call i1 @is_less_than_3(i32 [[ADD]]) #[[ATTR7]]1406; CGSCC-NEXT: ret i1 [[RET]]1407;1408 %csret1 = call i32 @cast_and_return(i1 true)1409 %csret2 = call i32 @cast_and_return(i1 %c)1410 %add = add i32 %csret1, %csret21411 %ret = call i1 @is_less_than_3(i32 %add)1412 ret i1 %ret1413}1414 1415define internal i32 @less_than_100_1(i32 %c) {1416; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1417; CGSCC-LABEL: define {{[^@]+}}@less_than_100_11418; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR2]] {1419; CGSCC-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [1420; CGSCC-NEXT: i32 0, label [[ONZERO:%.*]]1421; CGSCC-NEXT: i32 1, label [[ONONE:%.*]]1422; CGSCC-NEXT: i32 2, label [[ONTWO:%.*]]1423; CGSCC-NEXT: i32 3, label [[ONTHREE:%.*]]1424; CGSCC-NEXT: i32 4, label [[ONFOUR:%.*]]1425; CGSCC-NEXT: i32 5, label [[ONFIVE:%.*]]1426; CGSCC-NEXT: i32 6, label [[ONSIX:%.*]]1427; CGSCC-NEXT: ]1428; CGSCC: onzero:1429; CGSCC-NEXT: ret i32 01430; CGSCC: onone:1431; CGSCC-NEXT: ret i32 11432; CGSCC: ontwo:1433; CGSCC-NEXT: ret i32 21434; CGSCC: onthree:1435; CGSCC-NEXT: ret i32 31436; CGSCC: onfour:1437; CGSCC-NEXT: ret i32 41438; CGSCC: onfive:1439; CGSCC-NEXT: ret i32 51440; CGSCC: onsix:1441; CGSCC-NEXT: ret i32 61442; CGSCC: otherwise:1443; CGSCC-NEXT: ret i32 991444;1445 switch i32 %c, label %otherwise [ i32 0, label %onzero1446 i32 1, label %onone1447 i32 2, label %ontwo1448 i32 3, label %onthree1449 i32 4, label %onfour1450 i32 5, label %onfive1451 i32 6, label %onsix]1452onzero:1453 ret i32 01454onone:1455 ret i32 11456ontwo:1457 ret i32 21458onthree:1459 ret i32 31460onfour:1461 ret i32 41462onfive:1463 ret i32 51464onsix:1465 ret i32 61466otherwise:1467 ret i32 991468}1469 1470define internal i1 @is_less_than_100_1(i32 %c) {1471; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1472; CGSCC-LABEL: define {{[^@]+}}@is_less_than_100_11473; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR2]] {1474; CGSCC-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 1001475; CGSCC-NEXT: ret i1 [[CMP]]1476;1477 %cmp = icmp slt i32 %c, 1001478 ret i1 %cmp1479}1480 1481define i1 @propagate_range1(i32 %c){1482; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1483; TUNIT-LABEL: define {{[^@]+}}@propagate_range11484; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {1485; TUNIT-NEXT: ret i1 true1486;1487; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)1488; CGSCC-LABEL: define {{[^@]+}}@propagate_range11489; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR3]] {1490; CGSCC-NEXT: [[CSRET:%.*]] = call i32 @less_than_100_1(i32 noundef [[C]]) #[[ATTR7]]1491; CGSCC-NEXT: [[TRUE:%.*]] = call i1 @is_less_than_100_1(i32 noundef [[CSRET]]) #[[ATTR7]]1492; CGSCC-NEXT: ret i1 [[TRUE]]1493;1494 %csret = call i32 @less_than_100_1(i32 %c)1495 %true = call i1 @is_less_than_100_1(i32 %csret)1496 ret i1 %true1497}1498 1499define internal i32 @less_than_100_2(i32 %c) {1500;1501; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1502; TUNIT-LABEL: define {{[^@]+}}@less_than_100_21503; TUNIT-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] {1504; TUNIT-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [1505; TUNIT-NEXT: i32 0, label [[ONZERO:%.*]]1506; TUNIT-NEXT: i32 1, label [[ONONE:%.*]]1507; TUNIT-NEXT: i32 2, label [[ONTWO:%.*]]1508; TUNIT-NEXT: i32 3, label [[ONTHREE:%.*]]1509; TUNIT-NEXT: i32 4, label [[ONFOUR:%.*]]1510; TUNIT-NEXT: i32 5, label [[ONFIVE:%.*]]1511; TUNIT-NEXT: i32 6, label [[ONSIX:%.*]]1512; TUNIT-NEXT: ]1513; TUNIT: onzero:1514; TUNIT-NEXT: ret i32 01515; TUNIT: onone:1516; TUNIT-NEXT: ret i32 11517; TUNIT: ontwo:1518; TUNIT-NEXT: ret i32 21519; TUNIT: onthree:1520; TUNIT-NEXT: ret i32 31521; TUNIT: onfour:1522; TUNIT-NEXT: ret i32 41523; TUNIT: onfive:1524; TUNIT-NEXT: ret i32 51525; TUNIT: onsix:1526; TUNIT-NEXT: ret i32 61527; TUNIT: otherwise:1528; TUNIT-NEXT: ret i32 991529;1530; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1531; CGSCC-LABEL: define {{[^@]+}}@less_than_100_21532; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR2]] {1533; CGSCC-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [1534; CGSCC-NEXT: i32 0, label [[ONZERO:%.*]]1535; CGSCC-NEXT: i32 1, label [[ONONE:%.*]]1536; CGSCC-NEXT: i32 2, label [[ONTWO:%.*]]1537; CGSCC-NEXT: i32 3, label [[ONTHREE:%.*]]1538; CGSCC-NEXT: i32 4, label [[ONFOUR:%.*]]1539; CGSCC-NEXT: i32 5, label [[ONFIVE:%.*]]1540; CGSCC-NEXT: i32 6, label [[ONSIX:%.*]]1541; CGSCC-NEXT: ]1542; CGSCC: onzero:1543; CGSCC-NEXT: ret i32 01544; CGSCC: onone:1545; CGSCC-NEXT: ret i32 11546; CGSCC: ontwo:1547; CGSCC-NEXT: ret i32 21548; CGSCC: onthree:1549; CGSCC-NEXT: ret i32 31550; CGSCC: onfour:1551; CGSCC-NEXT: ret i32 41552; CGSCC: onfive:1553; CGSCC-NEXT: ret i32 51554; CGSCC: onsix:1555; CGSCC-NEXT: ret i32 61556; CGSCC: otherwise:1557; CGSCC-NEXT: ret i32 991558;1559 switch i32 %c, label %otherwise [ i32 0, label %onzero1560 i32 1, label %onone1561 i32 2, label %ontwo1562 i32 3, label %onthree1563 i32 4, label %onfour1564 i32 5, label %onfive1565 i32 6, label %onsix]1566onzero:1567 ret i32 01568onone:1569 ret i32 11570ontwo:1571 ret i32 21572onthree:1573 ret i32 31574onfour:1575 ret i32 41576onfive:1577 ret i32 51578onsix:1579 ret i32 61580otherwise:1581 ret i32 991582}1583 1584define internal i1 @is_less_than_100_2(i32 %c) {1585;1586; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1587; TUNIT-LABEL: define {{[^@]+}}@is_less_than_100_21588; TUNIT-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] {1589; TUNIT-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 1001590; TUNIT-NEXT: ret i1 [[CMP]]1591;1592; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1593; CGSCC-LABEL: define {{[^@]+}}@is_less_than_100_21594; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR2]] {1595; CGSCC-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 1001596; CGSCC-NEXT: ret i1 [[CMP]]1597;1598 %cmp = icmp slt i32 %c, 1001599 ret i1 %cmp1600}1601 1602define i1 @propagate_range2(i32 %c) {1603; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1604; TUNIT-LABEL: define {{[^@]+}}@propagate_range21605; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {1606; TUNIT-NEXT: [[CSRET1:%.*]] = call noundef i32 @less_than_100_2(i32 noundef 0) #[[ATTR4]]1607; TUNIT-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR4]]1608; TUNIT-NEXT: [[CSRET2:%.*]] = call noundef i32 @less_than_100_2(i32 noundef [[C]]) #[[ATTR4]]1609; TUNIT-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR4]]1610; TUNIT-NEXT: [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]]1611; TUNIT-NEXT: ret i1 [[TRUE]]1612;1613; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)1614; CGSCC-LABEL: define {{[^@]+}}@propagate_range21615; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR3]] {1616; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 noundef 0) #[[ATTR7]]1617; CGSCC-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR7]]1618; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 noundef [[C]]) #[[ATTR7]]1619; CGSCC-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR7]]1620; CGSCC-NEXT: [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]]1621; CGSCC-NEXT: ret i1 [[TRUE]]1622;1623 %csret1 = call i32 @less_than_100_2(i32 0)1624 %true1 = call i1 @is_less_than_100_2(i32 %csret1)1625 %csret2 = call i32 @less_than_100_2(i32 %c)1626 %true2 = call i1 @is_less_than_100_2(i32 %csret2)1627 %true = and i1 %true1, %true21628 ret i1 %true1629}1630 1631define internal i1 @non_zero(i8 %v) {1632; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1633; TUNIT-LABEL: define {{[^@]+}}@non_zero1634; TUNIT-SAME: (i8 [[V:%.*]]) #[[ATTR1]] {1635; TUNIT-NEXT: [[R:%.*]] = icmp ne i8 [[V]], 01636; TUNIT-NEXT: ret i1 [[R]]1637;1638; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)1639; CGSCC-LABEL: define {{[^@]+}}@non_zero1640; CGSCC-SAME: (i8 [[V:%.*]]) #[[ATTR2]] {1641; CGSCC-NEXT: ret i1 true1642;1643 %r = icmp ne i8 %v, 01644 ret i1 %r1645}1646 1647; Avoid range metadata for %l below1648define i1 @context(ptr %p) {1649; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)1650; TUNIT-LABEL: define {{[^@]+}}@context1651; TUNIT-SAME: (ptr nofree noundef nonnull readonly captures(none) dereferenceable(1) [[P:%.*]]) #[[ATTR0]] {1652; TUNIT-NEXT: [[L:%.*]] = load i8, ptr [[P]], align 11653; TUNIT-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]]1654; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]1655; TUNIT: t:1656; TUNIT-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) #[[ATTR4]]1657; TUNIT-NEXT: ret i1 [[R]]1658; TUNIT: f:1659; TUNIT-NEXT: ret i1 false1660;1661; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)1662; CGSCC-LABEL: define {{[^@]+}}@context1663; CGSCC-SAME: (ptr nofree noundef nonnull readonly captures(none) dereferenceable(1) [[P:%.*]]) #[[ATTR1]] {1664; CGSCC-NEXT: [[L:%.*]] = load i8, ptr [[P]], align 11665; CGSCC-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]]1666; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]1667; CGSCC: t:1668; CGSCC-NEXT: [[R:%.*]] = call noundef i1 @non_zero(i8 [[L]]) #[[ATTR7]]1669; CGSCC-NEXT: ret i1 [[R]]1670; CGSCC: f:1671; CGSCC-NEXT: ret i1 false1672;1673 %l = load i8, ptr %p1674 %c = icmp slt i8 0, %l1675 br i1 %c, label %t, label %f1676t:1677 %r = call i1 @non_zero(i8 %l)1678 ret i1 %r1679f:1680 ret i1 false1681}1682 1683 1684define void @spam(ptr %arg, ptr %arg1) {1685; CHECK-LABEL: define {{[^@]+}}@spam1686; CHECK-SAME: (ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(4) [[ARG:%.*]], ptr nofree readnone captures(none) [[ARG1:%.*]]) {1687; CHECK-NEXT: bb:1688; CHECK-NEXT: [[TMP:%.*]] = load i32, ptr [[ARG]], align 81689; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP]], 41690; CHECK-NEXT: br i1 [[TMP2]], label [[BB3:%.*]], label [[BB4:%.*]]1691; CHECK: bb3:1692; CHECK-NEXT: call fastcc void @wobble(i32 signext [[TMP]])1693; CHECK-NEXT: br label [[BB5:%.*]]1694; CHECK: bb4:1695; CHECK-NEXT: call void @ham(i32 [[TMP]])1696; CHECK-NEXT: br label [[BB5]]1697; CHECK: bb5:1698; CHECK-NEXT: ret void1699;1700bb:1701 %tmp = load i32, ptr %arg, align 81702 %tmp2 = icmp ult i32 %tmp, 41703 br i1 %tmp2, label %bb3, label %bb41704 1705bb3: ; preds = %bb1706 call fastcc void @wobble(i32 signext %tmp)1707 br label %bb51708 1709bb4: ; preds = %bb1710 call void @ham(i32 %tmp)1711 br label %bb51712 1713bb5: ; preds = %bb4, %bb31714 ret void1715}1716 1717define internal fastcc void @wobble(i32 signext %arg) {1718; CHECK-LABEL: define {{[^@]+}}@wobble1719; CHECK-SAME: (i32 signext [[ARG:%.*]]) {1720; CHECK-NEXT: bb:1721; CHECK-NEXT: [[TMP:%.*]] = icmp ult i32 [[ARG]], 21722; CHECK-NEXT: br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]]1723; CHECK: bb1:1724; CHECK-NEXT: call void @barney(i32 noundef signext 32, i32 noundef signext 0)1725; CHECK-NEXT: br label [[BB3:%.*]]1726; CHECK: bb2:1727; CHECK-NEXT: br label [[BB3]]1728; CHECK: bb3:1729; CHECK-NEXT: ret void1730;1731bb:1732 %tmp = icmp ult i32 %arg, 21733 br i1 %tmp, label %bb1, label %bb21734 1735bb1: ; preds = %bb1736 call void @barney(i32 signext 32, i32 signext 0)1737 br label %bb31738 1739bb2: ; preds = %bb1740 br label %bb31741 1742bb3: ; preds = %bb2, %bb11743 ret void1744}1745 1746define i1 @loop_1(i32 %N) {1747; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none)1748; TUNIT-LABEL: define {{[^@]+}}@loop_11749; TUNIT-SAME: (i32 [[N:%.*]]) #[[ATTR2:[0-9]+]] {1750; TUNIT-NEXT: entry:1751; TUNIT-NEXT: br label [[HEADER:%.*]]1752; TUNIT: header:1753; TUNIT-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[AND:%.*]], [[HEADER]] ]1754; TUNIT-NEXT: [[INC:%.*]] = add i32 [[I]], 11755; TUNIT-NEXT: [[AND]] = and i32 [[INC]], 99991756; TUNIT-NEXT: [[CMP:%.*]] = icmp ne i32 [[N]], [[AND]]1757; TUNIT-NEXT: br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]1758; TUNIT: exit:1759; TUNIT-NEXT: [[R:%.*]] = icmp sle i32 [[I]], 51760; TUNIT-NEXT: ret i1 [[R]]1761;1762; CGSCC: Function Attrs: nofree norecurse nosync nounwind memory(none)1763; CGSCC-LABEL: define {{[^@]+}}@loop_11764; CGSCC-SAME: (i32 [[N:%.*]]) #[[ATTR4:[0-9]+]] {1765; CGSCC-NEXT: entry:1766; CGSCC-NEXT: br label [[HEADER:%.*]]1767; CGSCC: header:1768; CGSCC-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[AND:%.*]], [[HEADER]] ]1769; CGSCC-NEXT: [[INC:%.*]] = add i32 [[I]], 11770; CGSCC-NEXT: [[AND]] = and i32 [[INC]], 99991771; CGSCC-NEXT: [[CMP:%.*]] = icmp ne i32 [[N]], [[AND]]1772; CGSCC-NEXT: br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]1773; CGSCC: exit:1774; CGSCC-NEXT: [[R:%.*]] = icmp sle i32 [[I]], 51775; CGSCC-NEXT: ret i1 [[R]]1776;1777entry:1778 br label %header1779header:1780 %i = phi i32 [0, %entry], [%and, %header]1781 %inc = add i32 %i, 11782 %and = and i32 %inc, 99991783 %cmp = icmp ne i32 %N, %and1784 br i1 %cmp, label %header, label %exit1785exit:1786 %r = icmp sle i32 %i, 51787 ret i1 %r1788}1789 1790declare void @ham(i32)1791 1792declare void @barney(i32 signext, i32 signext)1793 1794 1795!0 = !{i32 0, i32 10}1796!1 = !{i32 10, i32 100}1797!2 = !{i32 2, i32 5}1798;.1799; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }1800; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }1801; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind memory(none) }1802; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn memory(read) }1803; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn memory(none) }1804;.1805; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }1806; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: read) }1807; CGSCC: attributes #[[ATTR2]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }1808; CGSCC: attributes #[[ATTR3]] = { mustprogress nofree nosync nounwind willreturn memory(none) }1809; CGSCC: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind memory(none) }1810; CGSCC: attributes #[[ATTR5]] = { nofree willreturn memory(read) }1811; CGSCC: attributes #[[ATTR6]] = { nofree willreturn }1812; CGSCC: attributes #[[ATTR7]] = { nofree nosync willreturn }1813;.1814; TUNIT: [[RNG0]] = !{i32 0, i32 10}1815; TUNIT: [[RNG1]] = !{i32 10, i32 100}1816;.1817; CGSCC: [[RNG0]] = !{i32 0, i32 10}1818; CGSCC: [[RNG1]] = !{i32 10, i32 100}1819;.1820