1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes 2; RUN: opt -enable-new-pm=0 -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=22 -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=20 -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:#.*]] { 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:#.*]] { 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]], [[RNG0:!range !.*]] 155; IS__TUNIT_NPM-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 [[CMP1]]) [[ATTR0]], [[RNG0]] 156; IS__TUNIT_NPM-NEXT: [[CMP2:%.*]] = call i32 @iszero3(i32 noundef 1) [[ATTR0]], [[RNG0]] 157; IS__TUNIT_NPM-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 [[CMP2]]) [[ATTR0]], [[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:#.*]] 165; IS__CGSCC_OPM-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 noundef [[CMP1]]) [[ATTR2]], [[RNG0:!range !.*]] 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]], [[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:#.*]], [[RNG0:!range !.*]] 175; IS__CGSCC_NPM-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 noundef [[CMP1]]) [[ATTR1]], [[RNG0]] 176; IS__CGSCC_NPM-NEXT: [[CMP2:%.*]] = call noundef i32 @iszero3(i32 noundef 1) [[ATTR1]], [[RNG0]] 177; IS__CGSCC_NPM-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 noundef [[CMP2]]) [[ATTR1]], [[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]], [[RNG0:!range !.*]] 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]], [[RNG1:!range !.*]] 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]], [[RNG1:!range !.*]] 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]], [[RNG1:!range !.*]] 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]], [[RNG0]] 274; IS__TUNIT_OPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) [[ATTR0]], [[RNG1:!range !.*]] 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]], [[RNG1]] 282; IS__TUNIT_NPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) [[ATTR0]], [[RNG2:!range !.*]] 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]], [[RNG1]] 290; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) [[ATTR2]], [[RNG2:!range !.*]] 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]], [[RNG1]] 298; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) [[ATTR1]], [[RNG2:!range !.*]] 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:#.*]] { 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:#.*]] { 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 switch i32 %c, label %otherwise [i32 1, label %a 503 i32 -1, label %b] 504a: 505 ret i32 1 506b: 507 ret i32 -1 508otherwise: 509 ret i32 undef 510} 511 512define i1 @potential_test10(i32 %c) { 513; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 514; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test10 515; IS__TUNIT____-SAME: (i32 [[C:%.*]]) [[ATTR0]] { 516; IS__TUNIT____-NEXT: ret i1 false 517; 518; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 519; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test10 520; IS__CGSCC____-SAME: (i32 [[C:%.*]]) [[ATTR0]] { 521; IS__CGSCC____-NEXT: ret i1 false 522; 523 %ret = call i32 @may_return_undef(i32 %c) 524 %cmp = icmp eq i32 %ret, 0 525 ret i1 %cmp 526} 527 528define i32 @optimize_undef_1(i1 %c) { 529; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 530; IS__TUNIT____-LABEL: define {{[^@]+}}@optimize_undef_1 531; IS__TUNIT____-SAME: (i1 [[C:%.*]]) [[ATTR0]] { 532; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 533; IS__TUNIT____: t: 534; IS__TUNIT____-NEXT: ret i32 0 535; IS__TUNIT____: f: 536; IS__TUNIT____-NEXT: ret i32 1 537; 538; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 539; IS__CGSCC____-LABEL: define {{[^@]+}}@optimize_undef_1 540; IS__CGSCC____-SAME: (i1 [[C:%.*]]) [[ATTR0]] { 541; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 542; IS__CGSCC____: t: 543; IS__CGSCC____-NEXT: ret i32 0 544; IS__CGSCC____: f: 545; IS__CGSCC____-NEXT: ret i32 1 546; 547 br i1 %c, label %t, label %f 548t: 549 ret i32 0 550f: 551 %undef = add i32 undef, 1 552 ret i32 %undef 553} 554 555define i32 @optimize_undef_2(i1 %c) { 556; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 557; IS__TUNIT____-LABEL: define {{[^@]+}}@optimize_undef_2 558; IS__TUNIT____-SAME: (i1 [[C:%.*]]) [[ATTR0]] { 559; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 560; IS__TUNIT____: t: 561; IS__TUNIT____-NEXT: ret i32 0 562; IS__TUNIT____: f: 563; IS__TUNIT____-NEXT: ret i32 -1 564; 565; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 566; IS__CGSCC____-LABEL: define {{[^@]+}}@optimize_undef_2 567; IS__CGSCC____-SAME: (i1 [[C:%.*]]) [[ATTR0]] { 568; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 569; IS__CGSCC____: t: 570; IS__CGSCC____-NEXT: ret i32 0 571; IS__CGSCC____: f: 572; IS__CGSCC____-NEXT: ret i32 -1 573; 574 br i1 %c, label %t, label %f 575t: 576 ret i32 0 577f: 578 %undef = sub i32 undef, 1 579 ret i32 %undef 580} 581 582define i32 @optimize_undef_3(i1 %c) { 583; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 584; IS__TUNIT____-LABEL: define {{[^@]+}}@optimize_undef_3 585; IS__TUNIT____-SAME: (i1 [[C:%.*]]) [[ATTR0]] { 586; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 587; IS__TUNIT____: t: 588; IS__TUNIT____-NEXT: ret i32 0 589; IS__TUNIT____: f: 590; IS__TUNIT____-NEXT: ret i32 1 591; 592; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 593; IS__CGSCC____-LABEL: define {{[^@]+}}@optimize_undef_3 594; IS__CGSCC____-SAME: (i1 [[C:%.*]]) [[ATTR0]] { 595; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 596; IS__CGSCC____: t: 597; IS__CGSCC____-NEXT: ret i32 0 598; IS__CGSCC____: f: 599; IS__CGSCC____-NEXT: ret i32 1 600; 601 br i1 %c, label %t, label %f 602t: 603 ret i32 0 604f: 605 %undef = icmp eq i32 undef, 0 606 %undef2 = zext i1 %undef to i32 607 ret i32 %undef2 608} 609 610 611; FIXME: returned value can be simplified to 0 612define i32 @potential_test11(i1 %c) { 613; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn 614; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test11 615; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] { 616; IS__TUNIT_OPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) [[ATTR0]], [[RNG2:!range !.*]] 617; IS__TUNIT_OPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) [[ATTR0]], [[RNG3:!range !.*]] 618; IS__TUNIT_OPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]] 619; IS__TUNIT_OPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], 0 620; IS__TUNIT_OPM-NEXT: ret i32 [[ACC2]] 621; 622; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn 623; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test11 624; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] { 625; IS__TUNIT_NPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) [[ATTR0]], [[RNG0]] 626; IS__TUNIT_NPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) [[ATTR0]], [[RNG3:!range !.*]] 627; IS__TUNIT_NPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]] 628; IS__TUNIT_NPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], 0 629; IS__TUNIT_NPM-NEXT: ret i32 [[ACC2]] 630; 631; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 632; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test11 633; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] { 634; IS__CGSCC_OPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) [[ATTR2]], [[RNG0]] 635; IS__CGSCC_OPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) [[ATTR2]], [[RNG3:!range !.*]] 636; IS__CGSCC_OPM-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) [[ATTR2]], [[RNG0]] 637; IS__CGSCC_OPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]] 638; IS__CGSCC_OPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]] 639; IS__CGSCC_OPM-NEXT: ret i32 [[ACC2]] 640; 641; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 642; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test11 643; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] { 644; IS__CGSCC_NPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) [[ATTR1]], [[RNG0]] 645; IS__CGSCC_NPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) [[ATTR1]], [[RNG3:!range !.*]] 646; IS__CGSCC_NPM-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) [[ATTR1]], [[RNG0]] 647; IS__CGSCC_NPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]] 648; IS__CGSCC_NPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]] 649; IS__CGSCC_NPM-NEXT: ret i32 [[ACC2]] 650; 651 %zero1 = call i32 @optimize_undef_1(i1 %c) 652 %zero2 = call i32 @optimize_undef_2(i1 %c) 653 %zero3 = call i32 @optimize_undef_3(i1 %c) 654 %acc1 = add i32 %zero1, %zero2 655 %acc2 = add i32 %acc1, %zero3 656 ret i32 %acc2 657} 658 659define i32 @optimize_poison_1(i1 %c) { 660; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn 661; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@optimize_poison_1 662; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] { 663; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 664; IS__TUNIT_OPM: t: 665; IS__TUNIT_OPM-NEXT: ret i32 0 666; IS__TUNIT_OPM: f: 667; IS__TUNIT_OPM-NEXT: ret i32 -1 668; 669; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn 670; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@optimize_poison_1 671; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] { 672; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 673; IS__TUNIT_NPM: t: 674; IS__TUNIT_NPM-NEXT: ret i32 0 675; IS__TUNIT_NPM: f: 676; IS__TUNIT_NPM-NEXT: ret i32 undef 677; 678; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 679; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@optimize_poison_1 680; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] { 681; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 682; IS__CGSCC_OPM: t: 683; IS__CGSCC_OPM-NEXT: ret i32 0 684; IS__CGSCC_OPM: f: 685; IS__CGSCC_OPM-NEXT: ret i32 -1 686; 687; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 688; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@optimize_poison_1 689; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] { 690; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 691; IS__CGSCC_NPM: t: 692; IS__CGSCC_NPM-NEXT: ret i32 0 693; IS__CGSCC_NPM: f: 694; IS__CGSCC_NPM-NEXT: ret i32 undef 695; 696 br i1 %c, label %t, label %f 697t: 698 ret i32 0 699f: 700 %poison = sub nuw i32 0, 1 701 ret i32 %poison 702} 703 704; FIXME: returned value can be simplified to 0 705define i32 @potential_test12(i1 %c) { 706; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn 707; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test12 708; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] { 709; IS__TUNIT_OPM-NEXT: [[ZERO:%.*]] = call noundef i32 @optimize_poison_1(i1 [[C]]) [[ATTR0]], [[RNG3]] 710; IS__TUNIT_OPM-NEXT: ret i32 [[ZERO]] 711; 712; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn 713; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test12 714; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] { 715; IS__TUNIT_NPM-NEXT: ret i32 0 716; 717; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 718; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test12 719; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] { 720; IS__CGSCC_OPM-NEXT: [[ZERO:%.*]] = call i32 @optimize_poison_1(i1 [[C]]) [[ATTR2]], [[RNG3]] 721; IS__CGSCC_OPM-NEXT: ret i32 [[ZERO]] 722; 723; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 724; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test12 725; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] { 726; IS__CGSCC_NPM-NEXT: ret i32 0 727; 728 %zero = call i32 @optimize_poison_1(i1 %c) 729 ret i32 %zero 730} 731 732; Test 13 733; Do not simplify %ret in the callee to `%c`. 734; The potential value of %c is {0, 1} (undef is merged). 735; However, we should not simplify `and i32 %c, 3` to `%c` 736 737define internal i32 @potential_test13_callee(i32 %c) { 738; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 739; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test13_callee 740; IS__TUNIT____-SAME: (i32 [[C:%.*]]) [[ATTR0]] { 741; IS__TUNIT____-NEXT: [[RET:%.*]] = and i32 [[C]], 3 742; IS__TUNIT____-NEXT: ret i32 [[RET]] 743; 744; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 745; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test13_callee 746; IS__CGSCC____-SAME: (i32 [[C:%.*]]) [[ATTR0]] { 747; IS__CGSCC____-NEXT: [[RET:%.*]] = and i32 [[C]], 3 748; IS__CGSCC____-NEXT: ret i32 [[RET]] 749; 750 %ret = and i32 %c, 3 751 ret i32 %ret 752} 753 754define i32 @potential_test13_caller1() { 755; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn 756; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test13_caller1 757; IS__TUNIT_OPM-SAME: () [[ATTR0]] { 758; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) [[ATTR0]], [[RNG2]] 759; IS__TUNIT_OPM-NEXT: ret i32 [[RET]] 760; 761; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn 762; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test13_caller1 763; IS__TUNIT_NPM-SAME: () [[ATTR0]] { 764; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) [[ATTR0]], [[RNG0]] 765; IS__TUNIT_NPM-NEXT: ret i32 [[RET]] 766; 767; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 768; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller1 769; IS__CGSCC_OPM-SAME: () [[ATTR0]] { 770; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) [[ATTR2]], [[RNG0]] 771; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] 772; 773; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 774; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller1 775; IS__CGSCC_NPM-SAME: () [[ATTR0]] { 776; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) [[ATTR1]], [[RNG0]] 777; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] 778; 779 %ret = call i32 @potential_test13_callee(i32 0) 780 ret i32 %ret 781} 782 783define i32 @potential_test13_caller2() { 784; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn 785; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test13_caller2 786; IS__TUNIT_OPM-SAME: () [[ATTR0]] { 787; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) [[ATTR0]], [[RNG2]] 788; IS__TUNIT_OPM-NEXT: ret i32 [[RET]] 789; 790; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn 791; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test13_caller2 792; IS__TUNIT_NPM-SAME: () [[ATTR0]] { 793; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) [[ATTR0]], [[RNG0]] 794; IS__TUNIT_NPM-NEXT: ret i32 [[RET]] 795; 796; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 797; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller2 798; IS__CGSCC_OPM-SAME: () [[ATTR0]] { 799; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) [[ATTR2]], [[RNG0]] 800; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] 801; 802; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 803; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller2 804; IS__CGSCC_NPM-SAME: () [[ATTR0]] { 805; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) [[ATTR1]], [[RNG0]] 806; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] 807; 808 %ret = call i32 @potential_test13_callee(i32 1) 809 ret i32 %ret 810} 811 812define i32 @potential_test13_caller3() { 813; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn 814; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test13_caller3 815; IS__TUNIT_OPM-SAME: () [[ATTR0]] { 816; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) [[ATTR0]], [[RNG2]] 817; IS__TUNIT_OPM-NEXT: ret i32 [[RET]] 818; 819; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn 820; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test13_caller3 821; IS__TUNIT_NPM-SAME: () [[ATTR0]] { 822; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) [[ATTR0]], [[RNG0]] 823; IS__TUNIT_NPM-NEXT: ret i32 [[RET]] 824; 825; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 826; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller3 827; IS__CGSCC_OPM-SAME: () [[ATTR0]] { 828; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) [[ATTR2]], [[RNG0]] 829; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] 830; 831; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 832; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller3 833; IS__CGSCC_NPM-SAME: () [[ATTR0]] { 834; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) [[ATTR1]], [[RNG0]] 835; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] 836; 837 %ret = call i32 @potential_test13_callee(i32 undef) 838 ret i32 %ret 839} 840 841define i1 @potential_test14(i1 %c0, i1 %c1, i1 %c2, i1 %c3) { 842; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 843; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test14 844; IS__TUNIT____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) [[ATTR0]] { 845; IS__TUNIT____-NEXT: [[X0:%.*]] = select i1 [[C0]], i32 0, i32 1 846; IS__TUNIT____-NEXT: [[X1:%.*]] = select i1 [[C1]], i32 [[X0]], i32 undef 847; IS__TUNIT____-NEXT: [[Y2:%.*]] = select i1 [[C2]], i32 0, i32 7 848; IS__TUNIT____-NEXT: [[Z3:%.*]] = select i1 [[C3]], i32 [[X1]], i32 [[Y2]] 849; IS__TUNIT____-NEXT: [[RET:%.*]] = icmp slt i32 [[Z3]], 7 850; IS__TUNIT____-NEXT: ret i1 [[RET]] 851; 852; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 853; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test14 854; IS__CGSCC____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) [[ATTR0]] { 855; IS__CGSCC____-NEXT: [[X0:%.*]] = select i1 [[C0]], i32 0, i32 1 856; IS__CGSCC____-NEXT: [[X1:%.*]] = select i1 [[C1]], i32 [[X0]], i32 undef 857; IS__CGSCC____-NEXT: [[Y2:%.*]] = select i1 [[C2]], i32 0, i32 7 858; IS__CGSCC____-NEXT: [[Z3:%.*]] = select i1 [[C3]], i32 [[X1]], i32 [[Y2]] 859; IS__CGSCC____-NEXT: [[RET:%.*]] = icmp slt i32 [[Z3]], 7 860; IS__CGSCC____-NEXT: ret i1 [[RET]] 861; 862 %x0 = select i1 %c0, i32 0, i32 1 863 %x1 = select i1 %c1, i32 %x0, i32 undef 864 %y2 = select i1 %c2, i32 0, i32 7 865 %z3 = select i1 %c3, i32 %x1, i32 %y2 866 %ret = icmp slt i32 %z3, 7 867 ret i1 %ret 868} 869 870define i1 @potential_test15(i1 %c0, i1 %c1) { 871; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 872; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test15 873; IS__TUNIT____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) [[ATTR0]] { 874; IS__TUNIT____-NEXT: ret i1 false 875; 876; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 877; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test15 878; IS__CGSCC____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) [[ATTR0]] { 879; IS__CGSCC____-NEXT: ret i1 false 880; 881 %x0 = select i1 %c0, i32 0, i32 1 882 %x1 = select i1 %c1, i32 %x0, i32 undef 883 %ret = icmp eq i32 %x1, 7 884 ret i1 %ret 885} 886 887define i1 @potential_test16(i1 %c0, i1 %c1) { 888; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 889; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test16 890; IS__TUNIT____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) [[ATTR0]] { 891; IS__TUNIT____-NEXT: ret i1 false 892; 893; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 894; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test16 895; IS__CGSCC____-SAME: (i1 [[C0:%.*]], i1 [[C1:%.*]]) [[ATTR0]] { 896; IS__CGSCC____-NEXT: ret i1 false 897; 898 %x0 = select i1 %c0, i32 0, i32 undef 899 %x1 = select i1 %c1, i32 %x0, i32 1 900 %ret = icmp eq i32 %x1, 7 901 ret i1 %ret 902} 903 904; IS__TUNIT_NPM: !0 = !{i32 0, i32 2} 905; IS__TUNIT_NPM: !1 = !{i32 1, i32 4} 906; IS__TUNIT_NPM: !2 = !{i32 3, i32 5} 907; IS__TUNIT_NPM: !3 = !{i32 -1, i32 1} 908; IS__TUNIT_NPM-NOT: !4 909 910; IS__TUNIT_OPM: !0 = !{i32 1, i32 4} 911; IS__TUNIT_OPM: !1 = !{i32 3, i32 5} 912; IS__TUNIT_OPM: !2 = !{i32 0, i32 2} 913; IS__TUNIT_OPM: !3 = !{i32 -1, i32 1} 914; IS__TUNIT_OPM-NOT: !4 915