1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals 2; RUN: opt -enable-new-pm=0 -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=20 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM 3; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=19 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM 4; RUN: opt -enable-new-pm=0 -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM 5; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM 6; 7; Test for multiple potential values 8; 9; potential-test 1 10; bool iszero(int c) { return c == 0; } 11; bool potential_test1(bool c) { return iszero(c ? 1 : -1); } 12 13define internal i1 @iszero1(i32 %c) { 14; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 15; IS__CGSCC____-LABEL: define {{[^@]+}}@iszero1 16; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] { 17; IS__CGSCC____-NEXT: ret i1 undef 18; 19 %cmp = icmp eq i32 %c, 0 20 ret i1 %cmp 21} 22 23define i1 @potential_test1(i1 %c) { 24; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 25; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test1 26; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] { 27; IS__TUNIT____-NEXT: ret i1 false 28; 29; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 30; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test1 31; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 32; IS__CGSCC____-NEXT: ret i1 false 33; 34 %arg = select i1 %c, i32 -1, i32 1 35 %ret = call i1 @iszero1(i32 %arg) 36 ret i1 %ret 37} 38 39 40; potential-test 2 41; 42; potential values of argument of iszero are {1,-1} 43; potential value of returned value of iszero is 0 44; 45; int call_with_two_values(int x) { return iszero(x) + iszero(-x); } 46; int potential_test2(int x) { return call_with_two_values(1) + call_with_two_values(-1); } 47 48define internal i32 @iszero2(i32 %c) { 49; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 50; IS__CGSCC____-LABEL: define {{[^@]+}}@iszero2 51; IS__CGSCC____-SAME: () #[[ATTR0]] { 52; IS__CGSCC____-NEXT: ret i32 undef 53; 54 %cmp = icmp eq i32 %c, 0 55 %ret = zext i1 %cmp to i32 56 ret i32 %ret 57} 58 59define internal i32 @call_with_two_values(i32 %c) { 60; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 61; IS__CGSCC____-LABEL: define {{[^@]+}}@call_with_two_values 62; IS__CGSCC____-SAME: () #[[ATTR0]] { 63; IS__CGSCC____-NEXT: ret i32 undef 64; 65 %csret1 = call i32 @iszero2(i32 %c) 66 %minusc = sub i32 0, %c 67 %csret2 = call i32 @iszero2(i32 %minusc) 68 %ret = add i32 %csret1, %csret2 69 ret i32 %ret 70} 71 72define i32 @potential_test2(i1 %c) { 73; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 74; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test2 75; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 76; IS__TUNIT____-NEXT: ret i32 0 77; 78; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 79; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test2 80; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 81; IS__CGSCC____-NEXT: ret i32 0 82; 83 %csret1 = call i32 @call_with_two_values(i32 1) 84 %csret2 = call i32 @call_with_two_values(i32 -1) 85 %ret = add i32 %csret1, %csret2 86 ret i32 %ret 87} 88 89 90; potential-test 3 91; 92; potential values of returned value of f are {0,1} 93; potential values of argument of g are {0,1} 94; potential value of returned value of g is 1 95; then returned value of g can be simplified 96; 97; int zero_or_one(int c) { return c < 2; } 98; int potential_test3() { return zero_or_one(iszero(0))+zero_or_one(iszero(1)); } 99 100define internal i32 @iszero3(i32 %c) { 101; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 102; IS__TUNIT____-LABEL: define {{[^@]+}}@iszero3 103; IS__TUNIT____-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] { 104; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 105; IS__TUNIT____-NEXT: [[RET:%.*]] = zext i1 [[CMP]] to i32 106; IS__TUNIT____-NEXT: ret i32 [[RET]] 107; 108; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 109; IS__CGSCC____-LABEL: define {{[^@]+}}@iszero3 110; IS__CGSCC____-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] { 111; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 112; IS__CGSCC____-NEXT: [[RET:%.*]] = zext i1 [[CMP]] to i32 113; IS__CGSCC____-NEXT: ret i32 [[RET]] 114; 115 %cmp = icmp eq i32 %c, 0 116 %ret = zext i1 %cmp to i32 117 ret i32 %ret 118} 119 120define internal i32 @less_than_two(i32 %c) { 121; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 122; IS__TUNIT____-LABEL: define {{[^@]+}}@less_than_two 123; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 124; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 2 125; IS__TUNIT____-NEXT: [[RET:%.*]] = zext i1 [[CMP]] to i32 126; IS__TUNIT____-NEXT: ret i32 [[RET]] 127; 128; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 129; IS__CGSCC____-LABEL: define {{[^@]+}}@less_than_two 130; IS__CGSCC____-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] { 131; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 2 132; IS__CGSCC____-NEXT: [[RET:%.*]] = zext i1 [[CMP]] to i32 133; IS__CGSCC____-NEXT: ret i32 [[RET]] 134; 135 %cmp = icmp slt i32 %c, 2 136 %ret = zext i1 %cmp to i32 137 ret i32 %ret 138} 139 140define i32 @potential_test3() { 141; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn 142; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test3 143; IS__TUNIT_OPM-SAME: () #[[ATTR0]] { 144; IS__TUNIT_OPM-NEXT: [[CMP1:%.*]] = call i32 @iszero3(i32 noundef 0) #[[ATTR0]] 145; IS__TUNIT_OPM-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 [[CMP1]]) #[[ATTR0]] 146; IS__TUNIT_OPM-NEXT: [[CMP2:%.*]] = call i32 @iszero3(i32 noundef 1) #[[ATTR0]] 147; IS__TUNIT_OPM-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 [[CMP2]]) #[[ATTR0]] 148; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = add i32 [[TRUE1]], [[TRUE2]] 149; IS__TUNIT_OPM-NEXT: ret i32 [[RET]] 150; 151; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn 152; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test3 153; IS__TUNIT_NPM-SAME: () #[[ATTR0]] { 154; IS__TUNIT_NPM-NEXT: [[CMP1:%.*]] = call i32 @iszero3(i32 noundef 0) #[[ATTR0]], !range [[RNG0:![0-9]+]] 155; IS__TUNIT_NPM-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 [[CMP1]]) #[[ATTR0]], !range [[RNG0]] 156; IS__TUNIT_NPM-NEXT: [[CMP2:%.*]] = call i32 @iszero3(i32 noundef 1) #[[ATTR0]], !range [[RNG0]] 157; IS__TUNIT_NPM-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 [[CMP2]]) #[[ATTR0]], !range [[RNG0]] 158; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = add i32 [[TRUE1]], [[TRUE2]] 159; IS__TUNIT_NPM-NEXT: ret i32 [[RET]] 160; 161; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 162; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test3 163; IS__CGSCC_OPM-SAME: () #[[ATTR0]] { 164; IS__CGSCC_OPM-NEXT: [[CMP1:%.*]] = call noundef i32 @iszero3(i32 noundef 0) #[[ATTR2:[0-9]+]] 165; IS__CGSCC_OPM-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 noundef [[CMP1]]) #[[ATTR2]], !range [[RNG0:![0-9]+]] 166; IS__CGSCC_OPM-NEXT: [[CMP2:%.*]] = call noundef i32 @iszero3(i32 noundef 1) #[[ATTR2]] 167; IS__CGSCC_OPM-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 noundef [[CMP2]]) #[[ATTR2]], !range [[RNG0]] 168; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = add i32 [[TRUE1]], [[TRUE2]] 169; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] 170; 171; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 172; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test3 173; IS__CGSCC_NPM-SAME: () #[[ATTR0]] { 174; IS__CGSCC_NPM-NEXT: [[CMP1:%.*]] = call noundef i32 @iszero3(i32 noundef 0) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]] 175; IS__CGSCC_NPM-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 noundef [[CMP1]]) #[[ATTR1]], !range [[RNG0]] 176; IS__CGSCC_NPM-NEXT: [[CMP2:%.*]] = call noundef i32 @iszero3(i32 noundef 1) #[[ATTR1]], !range [[RNG0]] 177; IS__CGSCC_NPM-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 noundef [[CMP2]]) #[[ATTR1]], !range [[RNG0]] 178; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = add i32 [[TRUE1]], [[TRUE2]] 179; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] 180; 181 %cmp1 = call i32 @iszero3(i32 0) 182 %true1 = call i32 @less_than_two(i32 %cmp1) 183 %cmp2 = call i32 @iszero3(i32 1) 184 %true2 = call i32 @less_than_two(i32 %cmp2) 185 %ret = add i32 %true1, %true2 186 ret i32 %ret 187} 188 189 190; potential-test 4,5 191; 192; simplified 193; int potential_test4(int c) { return return1or3(c) == 2; } 194; int potential_test5(int c) { return return1or3(c) == return2or4(c); } 195; 196; not simplified 197; int potential_test6(int c) { return return1or3(c) == 3; } 198; int potential_test7(int c) { return return1or3(c) == return3or4(c); } 199 200define i32 @potential_test4(i32 %c) { 201; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 202; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test4 203; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 204; IS__TUNIT____-NEXT: ret i32 0 205; 206; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 207; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test4 208; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 209; IS__CGSCC____-NEXT: ret i32 0 210; 211 %csret = call i32 @return1or3(i32 %c) 212 %false = icmp eq i32 %csret, 2 213 %ret = zext i1 %false to i32 214 ret i32 %ret 215} 216 217define i32 @potential_test5(i32 %c) { 218; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 219; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test5 220; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 221; IS__TUNIT____-NEXT: ret i32 0 222; 223; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 224; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test5 225; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 226; IS__CGSCC____-NEXT: ret i32 0 227; 228 %csret1 = call i32 @return1or3(i32 %c) 229 %csret2 = call i32 @return2or4(i32 %c) 230 %false = icmp eq i32 %csret1, %csret2 231 %ret = zext i1 %false to i32 232 ret i32 %ret 233} 234 235define i1 @potential_test6(i32 %c) { 236; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn 237; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test6 238; IS__TUNIT_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 239; IS__TUNIT_OPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR0]], !range [[RNG0:![0-9]+]] 240; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3 241; IS__TUNIT_OPM-NEXT: ret i1 [[RET]] 242; 243; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn 244; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test6 245; IS__TUNIT_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 246; IS__TUNIT_NPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR0]], !range [[RNG1:![0-9]+]] 247; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3 248; IS__TUNIT_NPM-NEXT: ret i1 [[RET]] 249; 250; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 251; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test6 252; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 253; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2]], !range [[RNG1:![0-9]+]] 254; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3 255; IS__CGSCC_OPM-NEXT: ret i1 [[RET]] 256; 257; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 258; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test6 259; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 260; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR1]], !range [[RNG1:![0-9]+]] 261; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3 262; IS__CGSCC_NPM-NEXT: ret i1 [[RET]] 263; 264 %csret1 = call i32 @return1or3(i32 %c) 265 %ret = icmp eq i32 %csret1, 3 266 ret i1 %ret 267} 268 269define i1 @potential_test7(i32 %c) { 270; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn 271; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test7 272; IS__TUNIT_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 273; IS__TUNIT_OPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR0]], !range [[RNG0]] 274; IS__TUNIT_OPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) #[[ATTR0]], !range [[RNG1:![0-9]+]] 275; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] 276; IS__TUNIT_OPM-NEXT: ret i1 [[RET]] 277; 278; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn 279; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test7 280; IS__TUNIT_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 281; IS__TUNIT_NPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR0]], !range [[RNG1]] 282; IS__TUNIT_NPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) #[[ATTR0]], !range [[RNG2:![0-9]+]] 283; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] 284; IS__TUNIT_NPM-NEXT: ret i1 [[RET]] 285; 286; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 287; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test7 288; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 289; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2]], !range [[RNG1]] 290; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) #[[ATTR2]], !range [[RNG2:![0-9]+]] 291; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] 292; IS__CGSCC_OPM-NEXT: ret i1 [[RET]] 293; 294; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 295; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test7 296; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 297; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR1]], !range [[RNG1]] 298; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) #[[ATTR1]], !range [[RNG2:![0-9]+]] 299; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] 300; IS__CGSCC_NPM-NEXT: ret i1 [[RET]] 301; 302 %csret1 = call i32 @return1or3(i32 %c) 303 %csret2 = call i32 @return3or4(i32 %c) 304 %ret = icmp eq i32 %csret1, %csret2 305 ret i1 %ret 306} 307 308define internal i32 @return1or3(i32 %c) { 309; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 310; IS__TUNIT____-LABEL: define {{[^@]+}}@return1or3 311; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 312; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 313; IS__TUNIT____-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 1, i32 3 314; IS__TUNIT____-NEXT: ret i32 [[RET]] 315; 316; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 317; IS__CGSCC____-LABEL: define {{[^@]+}}@return1or3 318; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 319; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 320; IS__CGSCC____-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 1, i32 3 321; IS__CGSCC____-NEXT: ret i32 [[RET]] 322; 323 %cmp = icmp eq i32 %c, 0 324 %ret = select i1 %cmp, i32 1, i32 3 325 ret i32 %ret 326} 327 328define internal i32 @return2or4(i32 %c) { 329; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 330; IS__CGSCC____-LABEL: define {{[^@]+}}@return2or4 331; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 332; IS__CGSCC____-NEXT: ret i32 undef 333; 334 %cmp = icmp eq i32 %c, 0 335 %ret = select i1 %cmp, i32 2, i32 4 336 ret i32 %ret 337} 338 339define internal i32 @return3or4(i32 %c) { 340; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 341; IS__TUNIT____-LABEL: define {{[^@]+}}@return3or4 342; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 343; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 344; IS__TUNIT____-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 3, i32 4 345; IS__TUNIT____-NEXT: ret i32 [[RET]] 346; 347; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 348; IS__CGSCC____-LABEL: define {{[^@]+}}@return3or4 349; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 350; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 351; IS__CGSCC____-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 3, i32 4 352; IS__CGSCC____-NEXT: ret i32 [[RET]] 353; 354 %cmp = icmp eq i32 %c, 0 355 %ret = select i1 %cmp, i32 3, i32 4 356 ret i32 %ret 357} 358 359; potential-test 8 360; 361; propagate argument to callsite argument 362 363define internal i1 @cmp_with_four(i32 %c) { 364; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 365; IS__CGSCC____-LABEL: define {{[^@]+}}@cmp_with_four 366; IS__CGSCC____-SAME: () #[[ATTR0]] { 367; IS__CGSCC____-NEXT: ret i1 undef 368; 369 %cmp = icmp eq i32 %c, 4 370 ret i1 %cmp 371} 372 373define internal i1 @wrapper(i32 %c) { 374; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 375; IS__CGSCC____-LABEL: define {{[^@]+}}@wrapper 376; IS__CGSCC____-SAME: () #[[ATTR0]] { 377; IS__CGSCC____-NEXT: ret i1 undef 378; 379 %ret = call i1 @cmp_with_four(i32 %c) 380 ret i1 %ret 381} 382 383define i1 @potential_test8() { 384; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 385; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test8 386; IS__TUNIT____-SAME: () #[[ATTR0]] { 387; IS__TUNIT____-NEXT: ret i1 false 388; 389; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 390; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test8 391; IS__CGSCC____-SAME: () #[[ATTR0]] { 392; IS__CGSCC____-NEXT: ret i1 false 393; 394 %res1 = call i1 @wrapper(i32 1) 395 %res3 = call i1 @wrapper(i32 3) 396 %res5 = call i1 @wrapper(i32 5) 397 %res13 = or i1 %res1, %res3 398 %res135 = or i1 %res13, %res5 399 ret i1 %res135 400} 401 402define i1 @potential_test9() { 403; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone 404; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test9 405; IS__TUNIT_OPM-SAME: () #[[ATTR1:[0-9]+]] { 406; IS__TUNIT_OPM-NEXT: entry: 407; IS__TUNIT_OPM-NEXT: br label [[COND:%.*]] 408; IS__TUNIT_OPM: cond: 409; IS__TUNIT_OPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_1:%.*]], [[INC:%.*]] ] 410; IS__TUNIT_OPM-NEXT: [[C_0:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[C_1:%.*]], [[INC]] ] 411; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 10 412; IS__TUNIT_OPM-NEXT: br i1 [[CMP]], label [[BODY:%.*]], label [[END:%.*]] 413; IS__TUNIT_OPM: body: 414; IS__TUNIT_OPM-NEXT: [[C_1]] = mul i32 [[C_0]], -1 415; IS__TUNIT_OPM-NEXT: br label [[INC]] 416; IS__TUNIT_OPM: inc: 417; IS__TUNIT_OPM-NEXT: [[I_1]] = add i32 [[I_0]], 1 418; IS__TUNIT_OPM-NEXT: br label [[COND]] 419; IS__TUNIT_OPM: end: 420; IS__TUNIT_OPM-NEXT: ret i1 false 421; 422; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn 423; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test9 424; IS__TUNIT_NPM-SAME: () #[[ATTR0]] { 425; IS__TUNIT_NPM-NEXT: entry: 426; IS__TUNIT_NPM-NEXT: br label [[COND:%.*]] 427; IS__TUNIT_NPM: cond: 428; IS__TUNIT_NPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_1:%.*]], [[INC:%.*]] ] 429; IS__TUNIT_NPM-NEXT: [[C_0:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[C_1:%.*]], [[INC]] ] 430; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 10 431; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[BODY:%.*]], label [[END:%.*]] 432; IS__TUNIT_NPM: body: 433; IS__TUNIT_NPM-NEXT: [[C_1]] = mul i32 [[C_0]], -1 434; IS__TUNIT_NPM-NEXT: br label [[INC]] 435; IS__TUNIT_NPM: inc: 436; IS__TUNIT_NPM-NEXT: [[I_1]] = add i32 [[I_0]], 1 437; IS__TUNIT_NPM-NEXT: br label [[COND]] 438; IS__TUNIT_NPM: end: 439; IS__TUNIT_NPM-NEXT: ret i1 false 440; 441; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone 442; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test9 443; IS__CGSCC_OPM-SAME: () #[[ATTR1:[0-9]+]] { 444; IS__CGSCC_OPM-NEXT: entry: 445; IS__CGSCC_OPM-NEXT: br label [[COND:%.*]] 446; IS__CGSCC_OPM: cond: 447; IS__CGSCC_OPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_1:%.*]], [[INC:%.*]] ] 448; IS__CGSCC_OPM-NEXT: [[C_0:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[C_1:%.*]], [[INC]] ] 449; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 10 450; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[BODY:%.*]], label [[END:%.*]] 451; IS__CGSCC_OPM: body: 452; IS__CGSCC_OPM-NEXT: [[C_1]] = mul i32 [[C_0]], -1 453; IS__CGSCC_OPM-NEXT: br label [[INC]] 454; IS__CGSCC_OPM: inc: 455; IS__CGSCC_OPM-NEXT: [[I_1]] = add i32 [[I_0]], 1 456; IS__CGSCC_OPM-NEXT: br label [[COND]] 457; IS__CGSCC_OPM: end: 458; IS__CGSCC_OPM-NEXT: ret i1 false 459; 460; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 461; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test9 462; IS__CGSCC_NPM-SAME: () #[[ATTR0]] { 463; IS__CGSCC_NPM-NEXT: entry: 464; IS__CGSCC_NPM-NEXT: br label [[COND:%.*]] 465; IS__CGSCC_NPM: cond: 466; IS__CGSCC_NPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_1:%.*]], [[INC:%.*]] ] 467; IS__CGSCC_NPM-NEXT: [[C_0:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[C_1:%.*]], [[INC]] ] 468; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 10 469; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[BODY:%.*]], label [[END:%.*]] 470; IS__CGSCC_NPM: body: 471; IS__CGSCC_NPM-NEXT: [[C_1]] = mul i32 [[C_0]], -1 472; IS__CGSCC_NPM-NEXT: br label [[INC]] 473; IS__CGSCC_NPM: inc: 474; IS__CGSCC_NPM-NEXT: [[I_1]] = add i32 [[I_0]], 1 475; IS__CGSCC_NPM-NEXT: br label [[COND]] 476; IS__CGSCC_NPM: end: 477; IS__CGSCC_NPM-NEXT: ret i1 false 478; 479entry: 480 br label %cond 481cond: 482 %i.0 = phi i32 [0, %entry], [%i.1, %inc] 483 %c.0 = phi i32 [1, %entry], [%c.1, %inc] 484 %cmp = icmp slt i32 %i.0, 10 485 br i1 %cmp, label %body, label %end 486body: 487 %c.1 = mul i32 %c.0, -1 488 br label %inc 489inc: 490 %i.1 = add i32 %i.0, 1 491 br label %cond 492end: 493 %ret = icmp eq i32 %c.0, 0 494 ret i1 %ret 495} 496 497; Test 10 498; FIXME: potential returned values of @may_return_undef is {1, -1} 499; and returned value of @potential_test10 can be simplified to 0(false) 500 501define internal i32 @may_return_undef(i32 %c) { 502; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 503; IS__CGSCC____-LABEL: define {{[^@]+}}@may_return_undef 504; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 505; IS__CGSCC____-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [ 506; IS__CGSCC____-NEXT: i32 1, label [[A:%.*]] 507; IS__CGSCC____-NEXT: i32 -1, label [[B:%.*]] 508; IS__CGSCC____-NEXT: ] 509; IS__CGSCC____: a: 510; IS__CGSCC____-NEXT: ret i32 undef 511; IS__CGSCC____: b: 512; IS__CGSCC____-NEXT: ret i32 undef 513; IS__CGSCC____: otherwise: 514; IS__CGSCC____-NEXT: ret i32 undef 515; 516 switch i32 %c, label %otherwise [i32 1, label %a 517 i32 -1, label %b] 518a: 519 ret i32 1 520b: 521 ret i32 -1 522otherwise: 523 ret i32 undef 524} 525 526define i1 @potential_test10(i32 %c) { 527; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 528; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test10 529; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 530; IS__TUNIT____-NEXT: ret i1 false 531; 532; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 533; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test10 534; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 535; IS__CGSCC____-NEXT: ret i1 false 536; 537 %ret = call i32 @may_return_undef(i32 %c) 538 %cmp = icmp eq i32 %ret, 0 539 ret i1 %cmp 540} 541 542define i32 @optimize_undef_1(i1 %c) { 543; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 544; IS__TUNIT____-LABEL: define {{[^@]+}}@optimize_undef_1 545; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 546; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 547; IS__TUNIT____: t: 548; IS__TUNIT____-NEXT: ret i32 0 549; IS__TUNIT____: f: 550; IS__TUNIT____-NEXT: ret i32 1 551; 552; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 553; IS__CGSCC____-LABEL: define {{[^@]+}}@optimize_undef_1 554; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 555; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 556; IS__CGSCC____: t: 557; IS__CGSCC____-NEXT: ret i32 0 558; IS__CGSCC____: f: 559; IS__CGSCC____-NEXT: ret i32 1 560; 561 br i1 %c, label %t, label %f 562t: 563 ret i32 0 564f: 565 %undef = add i32 undef, 1 566 ret i32 %undef 567} 568 569define i32 @optimize_undef_2(i1 %c) { 570; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 571; IS__TUNIT____-LABEL: define {{[^@]+}}@optimize_undef_2 572; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 573; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 574; IS__TUNIT____: t: 575; IS__TUNIT____-NEXT: ret i32 0 576; IS__TUNIT____: f: 577; IS__TUNIT____-NEXT: ret i32 -1 578; 579; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 580; IS__CGSCC____-LABEL: define {{[^@]+}}@optimize_undef_2 581; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 582; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 583; IS__CGSCC____: t: 584; IS__CGSCC____-NEXT: ret i32 0 585; IS__CGSCC____: f: 586; IS__CGSCC____-NEXT: ret i32 -1 587; 588 br i1 %c, label %t, label %f 589t: 590 ret i32 0 591f: 592 %undef = sub i32 undef, 1 593 ret i32 %undef 594} 595 596define i32 @optimize_undef_3(i1 %c) { 597; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 598; IS__TUNIT____-LABEL: define {{[^@]+}}@optimize_undef_3 599; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 600; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 601; IS__TUNIT____: t: 602; IS__TUNIT____-NEXT: ret i32 0 603; IS__TUNIT____: f: 604; IS__TUNIT____-NEXT: ret i32 1 605; 606; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 607; IS__CGSCC____-LABEL: define {{[^@]+}}@optimize_undef_3 608; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 609; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 610; IS__CGSCC____: t: 611; IS__CGSCC____-NEXT: ret i32 0 612; IS__CGSCC____: f: 613; IS__CGSCC____-NEXT: ret i32 1 614; 615 br i1 %c, label %t, label %f 616t: 617 ret i32 0 618f: 619 %undef = icmp eq i32 undef, 0 620 %undef2 = zext i1 %undef to i32 621 ret i32 %undef2 622} 623 624 625; FIXME: returned value can be simplified to 0 626define i32 @potential_test11(i1 %c) { 627; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn 628; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test11 629; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 630; IS__TUNIT_OPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR0]], !range [[RNG2:![0-9]+]] 631; IS__TUNIT_OPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR0]], !range [[RNG3:![0-9]+]] 632; IS__TUNIT_OPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]] 633; IS__TUNIT_OPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], 0 634; IS__TUNIT_OPM-NEXT: ret i32 [[ACC2]] 635; 636; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn 637; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test11 638; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 639; IS__TUNIT_NPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR0]], !range [[RNG0]] 640; IS__TUNIT_NPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR0]], !range [[RNG3:![0-9]+]] 641; IS__TUNIT_NPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]] 642; IS__TUNIT_NPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], 0 643; IS__TUNIT_NPM-NEXT: ret i32 [[ACC2]] 644; 645; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 646; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test11 647; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 648; IS__CGSCC_OPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR2]], !range [[RNG0]] 649; IS__CGSCC_OPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR2]], !range [[RNG3:![0-9]+]] 650; IS__CGSCC_OPM-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) #[[ATTR2]], !range [[RNG0]] 651; IS__CGSCC_OPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]] 652; IS__CGSCC_OPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]] 653; IS__CGSCC_OPM-NEXT: ret i32 [[ACC2]] 654; 655; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 656; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test11 657; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 658; IS__CGSCC_NPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR1]], !range [[RNG0]] 659; IS__CGSCC_NPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR1]], !range [[RNG3:![0-9]+]] 660; IS__CGSCC_NPM-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) #[[ATTR1]], !range [[RNG0]] 661; IS__CGSCC_NPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]] 662; IS__CGSCC_NPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]] 663; IS__CGSCC_NPM-NEXT: ret i32 [[ACC2]] 664; 665 %zero1 = call i32 @optimize_undef_1(i1 %c) 666 %zero2 = call i32 @optimize_undef_2(i1 %c) 667 %zero3 = call i32 @optimize_undef_3(i1 %c) 668 %acc1 = add i32 %zero1, %zero2 669 %acc2 = add i32 %acc1, %zero3 670 ret i32 %acc2 671} 672 673define i32 @optimize_poison_1(i1 %c) { 674; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn 675; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@optimize_poison_1 676; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 677; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 678; IS__TUNIT_OPM: t: 679; IS__TUNIT_OPM-NEXT: ret i32 0 680; IS__TUNIT_OPM: f: 681; IS__TUNIT_OPM-NEXT: ret i32 -1 682; 683; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn 684; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@optimize_poison_1 685; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 686; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 687; IS__TUNIT_NPM: t: 688; IS__TUNIT_NPM-NEXT: ret i32 0 689; IS__TUNIT_NPM: f: 690; IS__TUNIT_NPM-NEXT: ret i32 undef 691; 692; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 693; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@optimize_poison_1 694; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 695; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 696; IS__CGSCC_OPM: t: 697; IS__CGSCC_OPM-NEXT: ret i32 0 698; IS__CGSCC_OPM: f: 699; IS__CGSCC_OPM-NEXT: ret i32 -1 700; 701; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 702; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@optimize_poison_1 703; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 704; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 705; IS__CGSCC_NPM: t: 706; IS__CGSCC_NPM-NEXT: ret i32 0 707; IS__CGSCC_NPM: f: 708; IS__CGSCC_NPM-NEXT: ret i32 undef 709; 710 br i1 %c, label %t, label %f 711t: 712 ret i32 0 713f: 714 %poison = sub nuw i32 0, 1 715 ret i32 %poison 716} 717 718; FIXME: returned value can be simplified to 0 719define i32 @potential_test12(i1 %c) { 720; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn 721; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test12 722; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 723; IS__TUNIT_OPM-NEXT: [[ZERO:%.*]] = call noundef i32 @optimize_poison_1(i1 [[C]]) #[[ATTR0]], !range [[RNG3]] 724; IS__TUNIT_OPM-NEXT: ret i32 [[ZERO]] 725; 726; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn 727; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test12 728; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 729; IS__TUNIT_NPM-NEXT: ret i32 0 730; 731; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 732; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test12 733; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 734; IS__CGSCC_OPM-NEXT: [[ZERO:%.*]] = call i32 @optimize_poison_1(i1 [[C]]) #[[ATTR2]], !range [[RNG3]] 735; IS__CGSCC_OPM-NEXT: ret i32 [[ZERO]] 736; 737; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 738; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test12 739; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 740; IS__CGSCC_NPM-NEXT: ret i32 0 741; 742 %zero = call i32 @optimize_poison_1(i1 %c) 743 ret i32 %zero 744} 745 746; Test 13 747; Do not simplify %ret in the callee to `%c`. 748; The potential value of %c is {0, 1} (undef is merged). 749; However, we should not simplify `and i32 %c, 3` to `%c` 750 751define internal i32 @potential_test13_callee(i32 %c) { 752; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 753; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test13_callee 754; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 755; IS__TUNIT____-NEXT: [[RET:%.*]] = and i32 [[C]], 3 756; IS__TUNIT____-NEXT: ret i32 [[RET]] 757; 758; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 759; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test13_callee 760; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 761; IS__CGSCC____-NEXT: [[RET:%.*]] = and i32 [[C]], 3 762; IS__CGSCC____-NEXT: ret i32 [[RET]] 763; 764 %ret = and i32 %c, 3 765 ret i32 %ret 766} 767 768define i32 @potential_test13_caller1() { 769; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn 770; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test13_caller1 771; IS__TUNIT_OPM-SAME: () #[[ATTR0]] { 772; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR0]], !range [[RNG2]] 773; IS__TUNIT_OPM-NEXT: ret i32 [[RET]] 774; 775; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn 776; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test13_caller1 777; IS__TUNIT_NPM-SAME: () #[[ATTR0]] { 778; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR0]], !range [[RNG0]] 779; IS__TUNIT_NPM-NEXT: ret i32 [[RET]] 780; 781; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 782; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller1 783; IS__CGSCC_OPM-SAME: () #[[ATTR0]] { 784; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR2]], !range [[RNG0]] 785; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] 786; 787; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 788; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller1 789; IS__CGSCC_NPM-SAME: () #[[ATTR0]] { 790; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR1]], !range [[RNG0]] 791; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] 792; 793 %ret = call i32 @potential_test13_callee(i32 0) 794 ret i32 %ret 795} 796 797define i32 @potential_test13_caller2() { 798; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn 799; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test13_caller2 800; IS__TUNIT_OPM-SAME: () #[[ATTR0]] { 801; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR0]], !range [[RNG2]] 802; IS__TUNIT_OPM-NEXT: ret i32 [[RET]] 803; 804; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn 805; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test13_caller2 806; IS__TUNIT_NPM-SAME: () #[[ATTR0]] { 807; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR0]], !range [[RNG0]] 808; IS__TUNIT_NPM-NEXT: ret i32 [[RET]] 809; 810; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 811; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller2 812; IS__CGSCC_OPM-SAME: () #[[ATTR0]] { 813; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR2]], !range [[RNG0]] 814; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] 815; 816; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 817; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller2 818; IS__CGSCC_NPM-SAME: () #[[ATTR0]] { 819; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR1]], !range [[RNG0]] 820; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] 821; 822 %ret = call i32 @potential_test13_callee(i32 1) 823 ret i32 %ret 824} 825 826define i32 @potential_test13_caller3() { 827; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn 828; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test13_caller3 829; IS__TUNIT_OPM-SAME: () #[[ATTR0]] { 830; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) #[[ATTR0]], !range [[RNG2]] 831; IS__TUNIT_OPM-NEXT: ret i32 [[RET]] 832; 833; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn 834; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test13_caller3 835; IS__TUNIT_NPM-SAME: () #[[ATTR0]] { 836; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) #[[ATTR0]], !range [[RNG0]] 837; IS__TUNIT_NPM-NEXT: ret i32 [[RET]] 838; 839; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 840; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller3 841; IS__CGSCC_OPM-SAME: () #[[ATTR0]] { 842; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) #[[ATTR2]], !range [[RNG0]] 843; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] 844; 845; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 846; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller3 847; IS__CGSCC_NPM-SAME: () #[[ATTR0]] { 848; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) #[[ATTR1]], !range [[RNG0]] 849; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] 850; 851 %ret = call i32 @potential_test13_callee(i32 undef) 852 ret i32 %ret 853} 854 855define i1 @potential_test14(i1 %c0, i1 %c1, i1 %c2, i1 %c3) { 856; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 857; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test14 858; IS__TUNIT____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR0]] { 859; IS__TUNIT____-NEXT: [[X0:%.*]] = select i1 [[C0]], i32 0, i32 1 860; IS__TUNIT____-NEXT: [[X1:%.*]] = select i1 [[C1]], i32 [[X0]], i32 undef 861; IS__TUNIT____-NEXT: [[Y2:%.*]] = select i1 [[C2]], i32 0, i32 7 862; IS__TUNIT____-NEXT: [[Z3:%.*]] = select i1 [[C3]], i32 [[X1]], i32 [[Y2]] 863; IS__TUNIT____-NEXT: [[RET:%.*]] = icmp slt i32 [[Z3]], 7 864; IS__TUNIT____-NEXT: ret i1 [[RET]] 865; 866; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 867; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test14 868; IS__CGSCC____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR0]] { 869; IS__CGSCC____-NEXT: [[X0:%.*]] = select i1 [[C0]], i32 0, i32 1 870; IS__CGSCC____-NEXT: [[X1:%.*]] = select i1 [[C1]], i32 [[X0]], i32 undef 871; IS__CGSCC____-NEXT: [[Y2:%.*]] = select i1 [[C2]], i32 0, i32 7 872; IS__CGSCC____-NEXT: [[Z3:%.*]] = select i1 [[C3]], i32 [[X1]], i32 [[Y2]] 873; IS__CGSCC____-NEXT: [[RET:%.*]] = icmp slt i32 [[Z3]], 7 874; IS__CGSCC____-NEXT: ret i1 [[RET]] 875; 876 %x0 = select i1 %c0, i32 0, i32 1 877 %x1 = select i1 %c1, i32 %x0, i32 undef 878 %y2 = select i1 %c2, i32 0, i32 7 879 %z3 = select i1 %c3, i32 %x1, i32 %y2 880 %ret = icmp slt i32 %z3, 7 881 ret i1 %ret 882} 883 884define i1 @potential_test15(i1 %c0, i1 %c1) { 885; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 886; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test15 887; IS__TUNIT____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) #[[ATTR0]] { 888; IS__TUNIT____-NEXT: ret i1 false 889; 890; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 891; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test15 892; IS__CGSCC____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) #[[ATTR0]] { 893; IS__CGSCC____-NEXT: ret i1 false 894; 895 %x0 = select i1 %c0, i32 0, i32 1 896 %x1 = select i1 %c1, i32 %x0, i32 undef 897 %ret = icmp eq i32 %x1, 7 898 ret i1 %ret 899} 900 901define i1 @potential_test16(i1 %c0, i1 %c1) { 902; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 903; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test16 904; IS__TUNIT____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) #[[ATTR0]] { 905; IS__TUNIT____-NEXT: ret i1 false 906; 907; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 908; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test16 909; IS__CGSCC____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) #[[ATTR0]] { 910; IS__CGSCC____-NEXT: ret i1 false 911; 912 %x0 = select i1 %c0, i32 0, i32 undef 913 %x1 = select i1 %c1, i32 %x0, i32 1 914 %ret = icmp eq i32 %x1, 7 915 ret i1 %ret 916} 917 918;. 919; IS__TUNIT_OPM: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } 920; IS__TUNIT_OPM: attributes #[[ATTR1]] = { nofree nosync nounwind readnone } 921;. 922; IS__TUNIT_NPM: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } 923;. 924; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } 925; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone } 926; IS__CGSCC_OPM: attributes #[[ATTR2]] = { readnone willreturn } 927;. 928; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } 929; IS__CGSCC_NPM: attributes #[[ATTR1]] = { readnone willreturn } 930;. 931; IS__TUNIT_OPM: [[RNG0]] = !{i32 1, i32 4} 932; IS__TUNIT_OPM: [[RNG1]] = !{i32 3, i32 5} 933; IS__TUNIT_OPM: [[RNG2]] = !{i32 0, i32 2} 934; IS__TUNIT_OPM: [[RNG3]] = !{i32 -1, i32 1} 935;. 936; NOT_TUNIT_OPM: [[META0:![0-9]+]] = !{i32 0, i32 2} 937; NOT_TUNIT_OPM: [[META1:![0-9]+]] = !{i32 1, i32 4} 938; NOT_TUNIT_OPM: [[META2:![0-9]+]] = !{i32 3, i32 5} 939; NOT_TUNIT_OPM: [[META3:![0-9]+]] = !{i32 -1, i32 1} 940;. 941