brintos

brintos / llvm-project-archived public Read only

0
0
Text · 24.3 KiB · 11652f0 Raw
668 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; Test for multiple potential values6;7; potential-test 18; bool iszero(int c) { return c == 0; }9; bool potential_test1(bool c) { return iszero(c ? 1 : -1); }10 11define internal i1 @iszero1(i32 %c) {12; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)13; CGSCC-LABEL: define {{[^@]+}}@iszero114; CGSCC-SAME: () #[[ATTR0:[0-9]+]] {15; CGSCC-NEXT:    ret i1 false16;17  %cmp = icmp eq i32 %c, 018  ret i1 %cmp19}20 21define i1 @potential_test1(i1 %c) {22; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)23; TUNIT-LABEL: define {{[^@]+}}@potential_test124; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] {25; TUNIT-NEXT:    ret i1 false26;27; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)28; CGSCC-LABEL: define {{[^@]+}}@potential_test129; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1:[0-9]+]] {30; CGSCC-NEXT:    [[RET:%.*]] = call noundef i1 @iszero1() #[[ATTR2:[0-9]+]]31; CGSCC-NEXT:    ret i1 [[RET]]32;33  %arg = select i1 %c, i32 -1, i32 134  %ret = call i1 @iszero1(i32 %arg)35  ret i1 %ret36}37 38 39; potential-test 240;41; potential values of argument of iszero are {1,-1}42; potential value of returned value of iszero is 043;44; int call_with_two_values(int x) { return iszero(x) + iszero(-x); }45; int potential_test2(int x) { return call_with_two_values(1) + call_with_two_values(-1); }46 47define internal i32 @iszero2(i32 %c) {48; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)49; CGSCC-LABEL: define {{[^@]+}}@iszero250; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {51; CGSCC-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C]], 052; CGSCC-NEXT:    [[RET:%.*]] = zext i1 [[CMP]] to i3253; CGSCC-NEXT:    ret i32 [[RET]]54;55  %cmp = icmp eq i32 %c, 056  %ret = zext i1 %cmp to i3257  ret i32 %ret58}59 60define internal i32 @call_with_two_values(i32 %c) {61; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)62; CGSCC-LABEL: define {{[^@]+}}@call_with_two_values63; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] {64; CGSCC-NEXT:    [[CSRET1:%.*]] = call i32 @iszero2(i32 noundef [[C]]) #[[ATTR2]]65; CGSCC-NEXT:    [[MINUSC:%.*]] = sub i32 0, [[C]]66; CGSCC-NEXT:    [[CSRET2:%.*]] = call i32 @iszero2(i32 noundef [[MINUSC]]) #[[ATTR2]]67; CGSCC-NEXT:    [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]]68; CGSCC-NEXT:    ret i32 [[RET]]69;70  %csret1 = call i32 @iszero2(i32 %c)71  %minusc = sub i32 0, %c72  %csret2 = call i32 @iszero2(i32 %minusc)73  %ret = add i32 %csret1, %csret274  ret i32 %ret75}76 77define i32 @potential_test2(i1 %c) {78; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)79; TUNIT-LABEL: define {{[^@]+}}@potential_test280; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {81; TUNIT-NEXT:    ret i32 082;83; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)84; CGSCC-LABEL: define {{[^@]+}}@potential_test285; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {86; CGSCC-NEXT:    [[CSRET1:%.*]] = call i32 @call_with_two_values(i32 noundef 1) #[[ATTR2]]87; CGSCC-NEXT:    [[CSRET2:%.*]] = call i32 @call_with_two_values(i32 noundef -1) #[[ATTR2]]88; CGSCC-NEXT:    [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]]89; CGSCC-NEXT:    ret i32 [[RET]]90;91  %csret1 = call i32 @call_with_two_values(i32 1)92  %csret2 = call i32 @call_with_two_values(i32 -1)93  %ret = add i32 %csret1, %csret294  ret i32 %ret95}96 97 98; potential-test 399;100; potential values of returned value of f are {0,1}101; potential values of argument of g are {0,1}102; potential value of returned value of g is 1103; then returned value of g can be simplified104;105; int zero_or_one(int c) { return c < 2; }106; int potential_test3() { return zero_or_one(iszero(0))+zero_or_one(iszero(1)); }107 108define internal i32 @iszero3(i32 %c) {109; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)110; CGSCC-LABEL: define {{[^@]+}}@iszero3111; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] {112; CGSCC-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C]], 0113; CGSCC-NEXT:    [[RET:%.*]] = zext i1 [[CMP]] to i32114; CGSCC-NEXT:    ret i32 [[RET]]115;116  %cmp = icmp eq i32 %c, 0117  %ret = zext i1 %cmp to i32118  ret i32 %ret119}120 121define internal i32 @less_than_two(i32 %c) {122; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)123; CGSCC-LABEL: define {{[^@]+}}@less_than_two124; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] {125; CGSCC-NEXT:    [[CMP:%.*]] = icmp slt i32 [[C]], 2126; CGSCC-NEXT:    [[RET:%.*]] = zext i1 [[CMP]] to i32127; CGSCC-NEXT:    ret i32 [[RET]]128;129  %cmp = icmp slt i32 %c, 2130  %ret = zext i1 %cmp to i32131  ret i32 %ret132}133 134define i32 @potential_test3() {135; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)136; TUNIT-LABEL: define {{[^@]+}}@potential_test3137; TUNIT-SAME: () #[[ATTR0]] {138; TUNIT-NEXT:    ret i32 2139;140; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)141; CGSCC-LABEL: define {{[^@]+}}@potential_test3142; CGSCC-SAME: () #[[ATTR1]] {143; CGSCC-NEXT:    [[CMP1:%.*]] = call i32 @iszero3(i32 noundef 0) #[[ATTR2]]144; CGSCC-NEXT:    [[TRUE1:%.*]] = call i32 @less_than_two(i32 noundef [[CMP1]]) #[[ATTR2]]145; CGSCC-NEXT:    [[CMP2:%.*]] = call i32 @iszero3(i32 noundef 1) #[[ATTR2]]146; CGSCC-NEXT:    [[TRUE2:%.*]] = call i32 @less_than_two(i32 noundef [[CMP2]]) #[[ATTR2]]147; CGSCC-NEXT:    [[RET:%.*]] = add i32 [[TRUE1]], [[TRUE2]]148; CGSCC-NEXT:    ret i32 [[RET]]149;150  %cmp1 = call i32 @iszero3(i32 0)151  %true1 = call i32 @less_than_two(i32 %cmp1)152  %cmp2 = call i32 @iszero3(i32 1)153  %true2 = call i32 @less_than_two(i32 %cmp2)154  %ret = add i32 %true1, %true2155  ret i32 %ret156}157 158 159; potential-test 4,5160;161; simplified162; int potential_test4(int c) { return return1or3(c) == 2; }163; int potential_test5(int c) { return return1or3(c) == return2or4(c); }164;165; not simplified166; int potential_test6(int c) { return return1or3(c) == 3; }167; int potential_test7(int c) { return return1or3(c) == return3or4(c); }168 169define i32 @potential_test4(i32 %c) {170; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)171; TUNIT-LABEL: define {{[^@]+}}@potential_test4172; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {173; TUNIT-NEXT:    ret i32 0174;175; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)176; CGSCC-LABEL: define {{[^@]+}}@potential_test4177; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {178; CGSCC-NEXT:    [[CSRET:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2]]179; CGSCC-NEXT:    [[FALSE:%.*]] = icmp eq i32 [[CSRET]], 2180; CGSCC-NEXT:    [[RET:%.*]] = zext i1 [[FALSE]] to i32181; CGSCC-NEXT:    ret i32 [[RET]]182;183  %csret = call i32 @return1or3(i32 %c)184  %false = icmp eq i32 %csret, 2185  %ret = zext i1 %false to i32186  ret i32 %ret187}188 189define i32 @potential_test5(i32 %c) {190; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)191; TUNIT-LABEL: define {{[^@]+}}@potential_test5192; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {193; TUNIT-NEXT:    ret i32 0194;195; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)196; CGSCC-LABEL: define {{[^@]+}}@potential_test5197; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {198; CGSCC-NEXT:    [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2]]199; CGSCC-NEXT:    [[CSRET2:%.*]] = call i32 @return2or4(i32 [[C]]) #[[ATTR2]]200; CGSCC-NEXT:    [[FALSE:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]]201; CGSCC-NEXT:    [[RET:%.*]] = zext i1 [[FALSE]] to i32202; CGSCC-NEXT:    ret i32 [[RET]]203;204  %csret1 = call i32 @return1or3(i32 %c)205  %csret2 = call i32 @return2or4(i32 %c)206  %false = icmp eq i32 %csret1, %csret2207  %ret = zext i1 %false to i32208  ret i32 %ret209}210 211define i1 @potential_test6(i32 %c) {212; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)213; TUNIT-LABEL: define {{[^@]+}}@potential_test6214; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {215; TUNIT-NEXT:    [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR1:[0-9]+]]216; TUNIT-NEXT:    [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3217; TUNIT-NEXT:    ret i1 [[RET]]218;219; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)220; CGSCC-LABEL: define {{[^@]+}}@potential_test6221; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {222; CGSCC-NEXT:    [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2]]223; CGSCC-NEXT:    [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3224; CGSCC-NEXT:    ret i1 [[RET]]225;226  %csret1 = call i32 @return1or3(i32 %c)227  %ret = icmp eq i32 %csret1, 3228  ret i1 %ret229}230 231define i1 @potential_test7(i32 %c) {232; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)233; TUNIT-LABEL: define {{[^@]+}}@potential_test7234; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {235; TUNIT-NEXT:    [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR1]]236; TUNIT-NEXT:    [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) #[[ATTR1]]237; TUNIT-NEXT:    [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]]238; TUNIT-NEXT:    ret i1 [[RET]]239;240; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)241; CGSCC-LABEL: define {{[^@]+}}@potential_test7242; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {243; CGSCC-NEXT:    [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2]]244; CGSCC-NEXT:    [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) #[[ATTR2]]245; CGSCC-NEXT:    [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]]246; CGSCC-NEXT:    ret i1 [[RET]]247;248  %csret1 = call i32 @return1or3(i32 %c)249  %csret2 = call i32 @return3or4(i32 %c)250  %ret = icmp eq i32 %csret1, %csret2251  ret i1 %ret252}253 254define internal i32 @return1or3(i32 %c) {255; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)256; CHECK-LABEL: define {{[^@]+}}@return1or3257; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] {258; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C]], 0259; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 1, i32 3260; CHECK-NEXT:    ret i32 [[RET]]261;262  %cmp = icmp eq i32 %c, 0263  %ret = select i1 %cmp, i32 1, i32 3264  ret i32 %ret265}266 267define internal i32 @return2or4(i32 %c) {268; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)269; CGSCC-LABEL: define {{[^@]+}}@return2or4270; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {271; CGSCC-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C]], 0272; CGSCC-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 2, i32 4273; CGSCC-NEXT:    ret i32 [[RET]]274;275  %cmp = icmp eq i32 %c, 0276  %ret = select i1 %cmp, i32 2, i32 4277  ret i32 %ret278}279 280define internal i32 @return3or4(i32 %c) {281; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)282; CHECK-LABEL: define {{[^@]+}}@return3or4283; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {284; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C]], 0285; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 3, i32 4286; CHECK-NEXT:    ret i32 [[RET]]287;288  %cmp = icmp eq i32 %c, 0289  %ret = select i1 %cmp, i32 3, i32 4290  ret i32 %ret291}292 293; potential-test 8294;295; propagate argument to callsite argument296 297define internal i1 @cmp_with_four(i32 %c) {298; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)299; CGSCC-LABEL: define {{[^@]+}}@cmp_with_four300; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {301; CGSCC-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C]], 4302; CGSCC-NEXT:    ret i1 [[CMP]]303;304  %cmp = icmp eq i32 %c, 4305  ret i1 %cmp306}307 308define internal i1 @wrapper(i32 %c) {309; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)310; CGSCC-LABEL: define {{[^@]+}}@wrapper311; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] {312; CGSCC-NEXT:    [[RET:%.*]] = call i1 @cmp_with_four(i32 noundef [[C]]) #[[ATTR2]]313; CGSCC-NEXT:    ret i1 [[RET]]314;315  %ret = call i1 @cmp_with_four(i32 %c)316  ret i1 %ret317}318 319define i1 @potential_test8() {320; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)321; TUNIT-LABEL: define {{[^@]+}}@potential_test8322; TUNIT-SAME: () #[[ATTR0]] {323; TUNIT-NEXT:    ret i1 false324;325; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)326; CGSCC-LABEL: define {{[^@]+}}@potential_test8327; CGSCC-SAME: () #[[ATTR1]] {328; CGSCC-NEXT:    [[RES1:%.*]] = call i1 @wrapper(i32 noundef 1) #[[ATTR2]]329; CGSCC-NEXT:    [[RES3:%.*]] = call i1 @wrapper(i32 noundef 3) #[[ATTR2]]330; CGSCC-NEXT:    [[RES5:%.*]] = call i1 @wrapper(i32 noundef 5) #[[ATTR2]]331; CGSCC-NEXT:    [[RES13:%.*]] = or i1 [[RES1]], [[RES3]]332; CGSCC-NEXT:    [[RES135:%.*]] = or i1 [[RES13]], [[RES5]]333; CGSCC-NEXT:    ret i1 [[RES135]]334;335  %res1 = call i1 @wrapper(i32 1)336  %res3 = call i1 @wrapper(i32 3)337  %res5 = call i1 @wrapper(i32 5)338  %res13 = or i1 %res1, %res3339  %res135 =  or i1 %res13, %res5340  ret i1 %res135341}342 343define i1 @potential_test9() {344; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)345; CHECK-LABEL: define {{[^@]+}}@potential_test9346; CHECK-SAME: () #[[ATTR0]] {347; CHECK-NEXT:  entry:348; CHECK-NEXT:    br label [[COND:%.*]]349; CHECK:       cond:350; CHECK-NEXT:    [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_1:%.*]], [[INC:%.*]] ]351; CHECK-NEXT:    [[C_0:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[C_1:%.*]], [[INC]] ]352; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_0]], 10353; CHECK-NEXT:    br i1 [[CMP]], label [[BODY:%.*]], label [[END:%.*]]354; CHECK:       body:355; CHECK-NEXT:    [[C_1]] = mul i32 [[C_0]], -1356; CHECK-NEXT:    br label [[INC]]357; CHECK:       inc:358; CHECK-NEXT:    [[I_1]] = add i32 [[I_0]], 1359; CHECK-NEXT:    br label [[COND]]360; CHECK:       end:361; CHECK-NEXT:    ret i1 false362;363entry:364  br label %cond365cond:366  %i.0 = phi i32 [0, %entry], [%i.1, %inc]367  %c.0 = phi i32 [1, %entry], [%c.1, %inc]368  %cmp = icmp slt i32 %i.0, 10369  br i1 %cmp, label %body, label %end370body:371  %c.1 = mul i32 %c.0, -1372  br label %inc373inc:374  %i.1 = add i32 %i.0, 1375  br label %cond376end:377  %ret = icmp eq i32 %c.0, 0378  ret i1 %ret379}380 381; Test 10382; potential returned values of @may_return_undef is {1, -1}383; and returned value of @potential_test10 can be simplified to 0(false)384 385define internal i32 @may_return_undef(i32 %c) {386; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)387; CGSCC-LABEL: define {{[^@]+}}@may_return_undef388; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] {389; CGSCC-NEXT:    switch i32 [[C]], label [[OTHERWISE:%.*]] [390; CGSCC-NEXT:      i32 1, label [[A:%.*]]391; CGSCC-NEXT:      i32 -1, label [[B:%.*]]392; CGSCC-NEXT:    ]393; CGSCC:       a:394; CGSCC-NEXT:    ret i32 1395; CGSCC:       b:396; CGSCC-NEXT:    ret i32 -1397; CGSCC:       otherwise:398; CGSCC-NEXT:    ret i32 undef399;400  switch i32 %c, label %otherwise [i32 1, label %a401  i32 -1, label %b]402a:403  ret i32 1404b:405  ret i32 -1406otherwise:407  ret i32 undef408}409 410define i1 @potential_test10(i32 %c) {411; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)412; TUNIT-LABEL: define {{[^@]+}}@potential_test10413; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {414; TUNIT-NEXT:    ret i1 false415;416; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)417; CGSCC-LABEL: define {{[^@]+}}@potential_test10418; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] {419; CGSCC-NEXT:    [[RET:%.*]] = call i32 @may_return_undef(i32 noundef [[C]]) #[[ATTR2]]420; CGSCC-NEXT:    [[CMP:%.*]] = icmp eq i32 [[RET]], 0421; CGSCC-NEXT:    ret i1 [[CMP]]422;423  %ret = call i32 @may_return_undef(i32 %c)424  %cmp = icmp eq i32 %ret, 0425  ret i1 %cmp426}427 428define i32 @optimize_undef_1(i1 %c) {429; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)430; CHECK-LABEL: define {{[^@]+}}@optimize_undef_1431; CHECK-SAME: (i1 noundef [[C:%.*]]) #[[ATTR0]] {432; CHECK-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]433; CHECK:       t:434; CHECK-NEXT:    ret i32 0435; CHECK:       f:436; CHECK-NEXT:    [[UNDEF:%.*]] = add i32 undef, 1437; CHECK-NEXT:    ret i32 [[UNDEF]]438;439  br i1 %c, label %t, label %f440t:441  ret i32 0442f:443  %undef = add i32 undef, 1444  ret i32 %undef445}446 447define i32 @optimize_undef_2(i1 %c) {448; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)449; CHECK-LABEL: define {{[^@]+}}@optimize_undef_2450; CHECK-SAME: (i1 noundef [[C:%.*]]) #[[ATTR0]] {451; CHECK-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]452; CHECK:       t:453; CHECK-NEXT:    ret i32 0454; CHECK:       f:455; CHECK-NEXT:    [[UNDEF:%.*]] = sub i32 undef, 1456; CHECK-NEXT:    ret i32 [[UNDEF]]457;458  br i1 %c, label %t, label %f459t:460  ret i32 0461f:462  %undef = sub i32 undef, 1463  ret i32 %undef464}465 466define i32 @optimize_undef_3(i1 %c) {467; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)468; CHECK-LABEL: define {{[^@]+}}@optimize_undef_3469; CHECK-SAME: (i1 noundef [[C:%.*]]) #[[ATTR0]] {470; CHECK-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]471; CHECK:       t:472; CHECK-NEXT:    ret i32 0473; CHECK:       f:474; CHECK-NEXT:    ret i32 0475;476  br i1 %c, label %t, label %f477t:478  ret i32 0479f:480  %undef = icmp eq i32 undef, 0481  %undef2 = zext i1 %undef to i32482  ret i32 %undef2483}484 485 486; FIXME: returned value can be simplified to 0487define i32 @potential_test11(i1 %c) {488; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)489; TUNIT-LABEL: define {{[^@]+}}@potential_test11490; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {491; TUNIT-NEXT:    [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 noundef [[C]]) #[[ATTR1]]492; TUNIT-NEXT:    [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 noundef [[C]]) #[[ATTR1]]493; TUNIT-NEXT:    [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]]494; TUNIT-NEXT:    [[ACC2:%.*]] = add i32 [[ACC1]], 0495; TUNIT-NEXT:    ret i32 [[ACC2]]496;497; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)498; CGSCC-LABEL: define {{[^@]+}}@potential_test11499; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR1]] {500; CGSCC-NEXT:    [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 noundef [[C]]) #[[ATTR2]]501; CGSCC-NEXT:    [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 noundef [[C]]) #[[ATTR2]]502; CGSCC-NEXT:    [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 noundef [[C]]) #[[ATTR2]]503; CGSCC-NEXT:    [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]]504; CGSCC-NEXT:    [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]]505; CGSCC-NEXT:    ret i32 [[ACC2]]506;507  %zero1 = call i32 @optimize_undef_1(i1 %c)508  %zero2 = call i32 @optimize_undef_2(i1 %c)509  %zero3 = call i32 @optimize_undef_3(i1 %c)510  %acc1 = add i32 %zero1, %zero2511  %acc2 = add i32 %acc1, %zero3512  ret i32 %acc2513}514 515define i32 @optimize_poison_1(i1 %c) {516; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)517; CHECK-LABEL: define {{[^@]+}}@optimize_poison_1518; CHECK-SAME: (i1 noundef [[C:%.*]]) #[[ATTR0]] {519; CHECK-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]520; CHECK:       t:521; CHECK-NEXT:    ret i32 0522; CHECK:       f:523; CHECK-NEXT:    ret i32 0524;525  br i1 %c, label %t, label %f526t:527  ret i32 0528f:529  %poison = sub nuw i32 0, 1530  ret i32 %poison531}532 533; returned value can be simplified to 0534define i32 @potential_test12(i1 %c) {535; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)536; TUNIT-LABEL: define {{[^@]+}}@potential_test12537; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {538; TUNIT-NEXT:    ret i32 0539;540; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)541; CGSCC-LABEL: define {{[^@]+}}@potential_test12542; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR1]] {543; CGSCC-NEXT:    [[ZERO:%.*]] = call noundef i32 @optimize_poison_1(i1 noundef [[C]]) #[[ATTR2]]544; CGSCC-NEXT:    ret i32 [[ZERO]]545;546  %zero = call i32 @optimize_poison_1(i1 %c)547  ret i32 %zero548}549 550; Test 13551; Do not simplify %ret in the callee to `%c`.552; The potential value of %c is {0, 1} (undef is merged).553; However, we should not simplify `and i32 %c, 3` to `%c`554 555define internal i32 @potential_test13_callee(i32 %c) {556; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)557; CHECK-LABEL: define {{[^@]+}}@potential_test13_callee558; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {559; CHECK-NEXT:    [[RET:%.*]] = and i32 [[C]], 3560; CHECK-NEXT:    ret i32 [[RET]]561;562  %ret = and i32 %c, 3563  ret i32 %ret564}565 566define i32 @potential_test13_caller1() {567; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)568; TUNIT-LABEL: define {{[^@]+}}@potential_test13_caller1569; TUNIT-SAME: () #[[ATTR0]] {570; TUNIT-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR1]]571; TUNIT-NEXT:    ret i32 [[RET]]572;573; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)574; CGSCC-LABEL: define {{[^@]+}}@potential_test13_caller1575; CGSCC-SAME: () #[[ATTR1]] {576; CGSCC-NEXT:    [[RET:%.*]] = call noundef i32 @potential_test13_callee(i32 noundef 0) #[[ATTR2]]577; CGSCC-NEXT:    ret i32 [[RET]]578;579  %ret = call i32 @potential_test13_callee(i32 0)580  ret i32 %ret581}582 583define i32 @potential_test13_caller2() {584; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)585; TUNIT-LABEL: define {{[^@]+}}@potential_test13_caller2586; TUNIT-SAME: () #[[ATTR0]] {587; TUNIT-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR1]]588; TUNIT-NEXT:    ret i32 [[RET]]589;590; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)591; CGSCC-LABEL: define {{[^@]+}}@potential_test13_caller2592; CGSCC-SAME: () #[[ATTR1]] {593; CGSCC-NEXT:    [[RET:%.*]] = call noundef i32 @potential_test13_callee(i32 noundef 1) #[[ATTR2]]594; CGSCC-NEXT:    ret i32 [[RET]]595;596  %ret = call i32 @potential_test13_callee(i32 1)597  ret i32 %ret598}599 600define i32 @potential_test13_caller3() {601; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)602; TUNIT-LABEL: define {{[^@]+}}@potential_test13_caller3603; TUNIT-SAME: () #[[ATTR0]] {604; TUNIT-NEXT:    [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) #[[ATTR1]]605; TUNIT-NEXT:    ret i32 [[RET]]606;607; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)608; CGSCC-LABEL: define {{[^@]+}}@potential_test13_caller3609; CGSCC-SAME: () #[[ATTR1]] {610; CGSCC-NEXT:    [[RET:%.*]] = call noundef i32 @potential_test13_callee(i32 undef) #[[ATTR2]]611; CGSCC-NEXT:    ret i32 [[RET]]612;613  %ret = call i32 @potential_test13_callee(i32 undef)614  ret i32 %ret615}616 617define i1 @potential_test14(i1 %c0, i1 %c1, i1 %c2, i1 %c3) {618; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)619; CHECK-LABEL: define {{[^@]+}}@potential_test14620; CHECK-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR0]] {621; CHECK-NEXT:    [[X0:%.*]] = select i1 [[C0]], i32 0, i32 1622; CHECK-NEXT:    [[X1:%.*]] = select i1 [[C1]], i32 [[X0]], i32 undef623; CHECK-NEXT:    [[Y2:%.*]] = select i1 [[C2]], i32 0, i32 7624; CHECK-NEXT:    [[Z3:%.*]] = select i1 [[C3]], i32 [[X1]], i32 [[Y2]]625; CHECK-NEXT:    [[RET:%.*]] = icmp slt i32 [[Z3]], 7626; CHECK-NEXT:    ret i1 [[RET]]627;628  %x0 = select i1 %c0, i32 0, i32 1629  %x1 = select i1 %c1, i32 %x0, i32 undef630  %y2 = select i1 %c2, i32 0, i32 7631  %z3 = select i1 %c3, i32 %x1, i32 %y2632  %ret = icmp slt i32 %z3, 7633  ret i1 %ret634}635 636define i1 @potential_test15(i1 %c0, i1 %c1) {637; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)638; CHECK-LABEL: define {{[^@]+}}@potential_test15639; CHECK-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) #[[ATTR0]] {640; CHECK-NEXT:    ret i1 false641;642  %x0 = select i1 %c0, i32 0, i32 1643  %x1 = select i1 %c1, i32 %x0, i32 undef644  %ret = icmp eq i32 %x1, 7645  ret i1 %ret646}647 648define i1 @potential_test16(i1 %c0, i1 %c1) {649; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)650; CHECK-LABEL: define {{[^@]+}}@potential_test16651; CHECK-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) #[[ATTR0]] {652; CHECK-NEXT:    ret i1 false653;654  %x0 = select i1 %c0, i32 0, i32 undef655  %x1 = select i1 %c1, i32 %x0, i32 1656  %ret = icmp eq i32 %x1, 7657  ret i1 %ret658}659 660;.661; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }662; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(none) }663;.664; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }665; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(none) }666; CGSCC: attributes #[[ATTR2]] = { nofree nosync willreturn }667;.668