brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.2 KiB · 84e2c54 Raw
724 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals2; RUN: opt -passes=attributor -S < %s | FileCheck %s --check-prefixes=CHECK,OWRDL,UPTO2,UNLIM,OUNLM3; RUN: opt -passes=attributor -attributor-print-call-graph -S -disable-output < %s | FileCheck %s --check-prefixes=DOT4; RUN: opt -passes=attributor --attributor-max-specializations-per-call-base=2 -S < %s | FileCheck %s --check-prefixes=CHECK,OWRDL,UPTO2,LIMI25; RUN: opt -passes=attributor --attributor-max-specializations-per-call-base=0 -S < %s | FileCheck %s --check-prefixes=CHECK,OWRDL,LIMI06; RUN: opt -passes=attributor --attributor-assume-closed-world -S < %s | FileCheck %s --check-prefixes=CHECK,UPTO2,UNLIM,CWRLD7 8;.9; CHECK: @G = global ptr @usedByGlobal10;.11define dso_local void @func1() {12; CHECK-LABEL: @func1(13; CHECK-NEXT:    br label [[TMP2:%.*]]14; CHECK:       1:15; CHECK-NEXT:    unreachable16; CHECK:       2:17; CHECK-NEXT:    call void @func3()18; CHECK-NEXT:    ret void19;20  %1 = icmp ne i32 0, 021  br i1 %1, label %2, label %322 232:                                                ; preds = %024  call void @func2(i1 false)25  br label %326 273:                                                ; preds = %2, %028  call void () @func3()29  ret void30}31 32declare void @func3()33define internal void @func4() {34; CHECK-LABEL: @func4(35; CHECK-NEXT:    call void @func3()36; CHECK-NEXT:    ret void37;38  call void @func3()39  ret void40}41define internal void @internal_good() {42; CHECK-LABEL: @internal_good(43; CHECK-NEXT:    call void @void(ptr @func4)44; CHECK-NEXT:    ret void45;46  call void @void(ptr @func4)47  ret void48}49 50define dso_local void @func2(i1 %c) {51; UPTO2-LABEL: @func2(52; UPTO2-NEXT:    [[F:%.*]] = select i1 [[C:%.*]], ptr @internal_good, ptr @func453; UPTO2-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[F]], @func454; UPTO2-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]55; UPTO2:       2:56; UPTO2-NEXT:    call void @func4()57; UPTO2-NEXT:    br label [[TMP6:%.*]]58; UPTO2:       3:59; UPTO2-NEXT:    br i1 true, label [[TMP4:%.*]], label [[TMP5:%.*]]60; UPTO2:       4:61; UPTO2-NEXT:    call void @internal_good()62; UPTO2-NEXT:    br label [[TMP6]]63; UPTO2:       5:64; UPTO2-NEXT:    unreachable65; UPTO2:       6:66; UPTO2-NEXT:    ret void67;68; LIMI0-LABEL: @func2(69; LIMI0-NEXT:    [[F:%.*]] = select i1 [[C:%.*]], ptr @internal_good, ptr @func470; LIMI0-NEXT:    call void [[F]](), !callees [[META0:![0-9]+]]71; LIMI0-NEXT:    ret void72;73  %f = select i1 %c, ptr @internal_good, ptr @func474  call void %f()75  ret void76}77 78 79define void @func5(i32 %0) {80; UPTO2-LABEL: @func5(81; UPTO2-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP0:%.*]], 082; UPTO2-NEXT:    [[TMP3:%.*]] = select i1 [[TMP2]], ptr @func4, ptr @func383; UPTO2-NEXT:    [[TMP4:%.*]] = icmp eq ptr [[TMP3]], @func384; UPTO2-NEXT:    br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]85; UPTO2:       5:86; UPTO2-NEXT:    call void @func3()87; UPTO2-NEXT:    br label [[TMP9:%.*]]88; UPTO2:       6:89; UPTO2-NEXT:    br i1 true, label [[TMP7:%.*]], label [[TMP8:%.*]]90; UPTO2:       7:91; UPTO2-NEXT:    call void @func4()92; UPTO2-NEXT:    br label [[TMP9]]93; UPTO2:       8:94; UPTO2-NEXT:    unreachable95; UPTO2:       9:96; UPTO2-NEXT:    ret void97;98; LIMI0-LABEL: @func5(99; LIMI0-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP0:%.*]], 0100; LIMI0-NEXT:    [[TMP3:%.*]] = select i1 [[TMP2]], ptr @func4, ptr @func3101; LIMI0-NEXT:    call void [[TMP3]](), !callees [[META1:![0-9]+]]102; LIMI0-NEXT:    ret void103;104  %2 = icmp ne i32 %0, 0105  %3 = select i1 %2, ptr @func4, ptr @func3106  call void () %3()107  ret void108}109 110define i32 @musttailCall(i32 %0) {111; CHECK-LABEL: @musttailCall(112; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP0:%.*]], 0113; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP2]], ptr @func4, ptr @func3114; CHECK-NEXT:    [[C:%.*]] = musttail call i32 [[TMP3]](i32 0)115; CHECK-NEXT:    ret i32 [[C]]116;117  %2 = icmp ne i32 %0, 0118  %3 = select i1 %2, ptr @func4, ptr @func3119  %c = musttail call i32 (i32) %3(i32 0)120  ret i32 %c121}122 123declare i32 @retI32()124declare void @takeI32(i32)125declare float @retFloatTakeFloat(float)126; This callee is always filtered out because of the noundef argument127declare float @retFloatTakeFloatFloatNoundef(float, float noundef)128declare void @void()129 130define i32 @non_matching_fp1(i1 %c1, i1 %c2, i1 %c) {131; UNLIM-LABEL: @non_matching_fp1(132; UNLIM-NEXT:    [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32133; UNLIM-NEXT:    [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloat, ptr @void134; UNLIM-NEXT:    [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]135; UNLIM-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[FP]], @takeI32136; UNLIM-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]137; UNLIM:       2:138; UNLIM-NEXT:    [[CALL1:%.*]] = call i32 @takeI32(i32 42)139; UNLIM-NEXT:    br label [[TMP15:%.*]]140; UNLIM:       3:141; UNLIM-NEXT:    [[TMP4:%.*]] = icmp eq ptr [[FP]], @retI32142; UNLIM-NEXT:    br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]143; UNLIM:       5:144; UNLIM-NEXT:    [[CALL2:%.*]] = call i32 @retI32(i32 42)145; UNLIM-NEXT:    br label [[TMP15]]146; UNLIM:       6:147; UNLIM-NEXT:    [[TMP7:%.*]] = icmp eq ptr [[FP]], @void148; UNLIM-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]149; UNLIM:       8:150; UNLIM-NEXT:    [[CALL3:%.*]] = call i32 @void(i32 42)151; UNLIM-NEXT:    br label [[TMP15]]152; UNLIM:       9:153; UNLIM-NEXT:    br i1 true, label [[TMP10:%.*]], label [[TMP14:%.*]]154; UNLIM:       10:155; UNLIM-NEXT:    [[TMP11:%.*]] = bitcast i32 42 to float156; UNLIM-NEXT:    [[TMP12:%.*]] = call float @retFloatTakeFloat(float [[TMP11]])157; UNLIM-NEXT:    [[TMP13:%.*]] = bitcast float [[TMP12]] to i32158; UNLIM-NEXT:    br label [[TMP15]]159; UNLIM:       14:160; UNLIM-NEXT:    unreachable161; UNLIM:       15:162; UNLIM-NEXT:    [[CALL_PHI:%.*]] = phi i32 [ [[CALL1]], [[TMP2]] ], [ [[CALL2]], [[TMP5]] ], [ [[CALL3]], [[TMP8]] ], [ [[TMP13]], [[TMP10]] ]163; UNLIM-NEXT:    ret i32 [[CALL_PHI]]164;165; LIMI2-LABEL: @non_matching_fp1(166; LIMI2-NEXT:    [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32167; LIMI2-NEXT:    [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloat, ptr @void168; LIMI2-NEXT:    [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]169; LIMI2-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[FP]], @takeI32170; LIMI2-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]171; LIMI2:       2:172; LIMI2-NEXT:    [[CALL1:%.*]] = call i32 @takeI32(i32 42)173; LIMI2-NEXT:    br label [[TMP7:%.*]]174; LIMI2:       3:175; LIMI2-NEXT:    [[TMP4:%.*]] = icmp eq ptr [[FP]], @retI32176; LIMI2-NEXT:    br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]177; LIMI2:       5:178; LIMI2-NEXT:    [[CALL2:%.*]] = call i32 @retI32(i32 42)179; LIMI2-NEXT:    br label [[TMP7]]180; LIMI2:       6:181; LIMI2-NEXT:    [[CALL3:%.*]] = call i32 [[FP]](i32 42), !callees [[META0:![0-9]+]]182; LIMI2-NEXT:    br label [[TMP7]]183; LIMI2:       7:184; LIMI2-NEXT:    [[CALL_PHI:%.*]] = phi i32 [ [[CALL1]], [[TMP2]] ], [ [[CALL2]], [[TMP5]] ], [ [[CALL3]], [[TMP6]] ]185; LIMI2-NEXT:    ret i32 [[CALL_PHI]]186;187; LIMI0-LABEL: @non_matching_fp1(188; LIMI0-NEXT:    [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32189; LIMI0-NEXT:    [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloat, ptr @void190; LIMI0-NEXT:    [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]191; LIMI0-NEXT:    [[CALL:%.*]] = call i32 [[FP]](i32 42), !callees [[META2:![0-9]+]]192; LIMI0-NEXT:    ret i32 [[CALL]]193;194  %fp1 = select i1 %c1, ptr @retI32, ptr @takeI32195  %fp2 = select i1 %c2, ptr @retFloatTakeFloat, ptr @void196  %fp = select i1 %c, ptr %fp1, ptr %fp2197  %call = call i32 %fp(i32 42)198  ret i32 %call199}200 201define i32 @non_matching_fp1_noundef(i1 %c1, i1 %c2, i1 %c) {202; UNLIM-LABEL: @non_matching_fp1_noundef(203; UNLIM-NEXT:    [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32204; UNLIM-NEXT:    [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloatFloatNoundef, ptr @void205; UNLIM-NEXT:    [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]206; UNLIM-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[FP]], @takeI32207; UNLIM-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]208; UNLIM:       2:209; UNLIM-NEXT:    [[CALL1:%.*]] = call i32 @takeI32(i32 42)210; UNLIM-NEXT:    br label [[TMP9:%.*]]211; UNLIM:       3:212; UNLIM-NEXT:    [[TMP4:%.*]] = icmp eq ptr [[FP]], @retI32213; UNLIM-NEXT:    br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]214; UNLIM:       5:215; UNLIM-NEXT:    [[CALL2:%.*]] = call i32 @retI32(i32 42)216; UNLIM-NEXT:    br label [[TMP9]]217; UNLIM:       6:218; UNLIM-NEXT:    br i1 true, label [[TMP7:%.*]], label [[TMP8:%.*]]219; UNLIM:       7:220; UNLIM-NEXT:    [[CALL3:%.*]] = call i32 @void(i32 42)221; UNLIM-NEXT:    br label [[TMP9]]222; UNLIM:       8:223; UNLIM-NEXT:    unreachable224; UNLIM:       9:225; UNLIM-NEXT:    [[CALL_PHI:%.*]] = phi i32 [ [[CALL1]], [[TMP2]] ], [ [[CALL2]], [[TMP5]] ], [ [[CALL3]], [[TMP7]] ]226; UNLIM-NEXT:    ret i32 [[CALL_PHI]]227;228; LIMI2-LABEL: @non_matching_fp1_noundef(229; LIMI2-NEXT:    [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32230; LIMI2-NEXT:    [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloatFloatNoundef, ptr @void231; LIMI2-NEXT:    [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]232; LIMI2-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[FP]], @takeI32233; LIMI2-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]234; LIMI2:       2:235; LIMI2-NEXT:    [[CALL1:%.*]] = call i32 @takeI32(i32 42)236; LIMI2-NEXT:    br label [[TMP7:%.*]]237; LIMI2:       3:238; LIMI2-NEXT:    [[TMP4:%.*]] = icmp eq ptr [[FP]], @retI32239; LIMI2-NEXT:    br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]240; LIMI2:       5:241; LIMI2-NEXT:    [[CALL2:%.*]] = call i32 @retI32(i32 42)242; LIMI2-NEXT:    br label [[TMP7]]243; LIMI2:       6:244; LIMI2-NEXT:    [[CALL3:%.*]] = call i32 [[FP]](i32 42), !callees [[META1:![0-9]+]]245; LIMI2-NEXT:    br label [[TMP7]]246; LIMI2:       7:247; LIMI2-NEXT:    [[CALL_PHI:%.*]] = phi i32 [ [[CALL1]], [[TMP2]] ], [ [[CALL2]], [[TMP5]] ], [ [[CALL3]], [[TMP6]] ]248; LIMI2-NEXT:    ret i32 [[CALL_PHI]]249;250; LIMI0-LABEL: @non_matching_fp1_noundef(251; LIMI0-NEXT:    [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32252; LIMI0-NEXT:    [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloatFloatNoundef, ptr @void253; LIMI0-NEXT:    [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]254; LIMI0-NEXT:    [[CALL:%.*]] = call i32 [[FP]](i32 42), !callees [[META3:![0-9]+]]255; LIMI0-NEXT:    ret i32 [[CALL]]256;257  %fp1 = select i1 %c1, ptr @retI32, ptr @takeI32258  %fp2 = select i1 %c2, ptr @retFloatTakeFloatFloatNoundef, ptr @void259  %fp = select i1 %c, ptr %fp1, ptr %fp2260  %call = call i32 %fp(i32 42)261  ret i32 %call262}263 264define void @non_matching_fp2(i1 %c1, i1 %c2, i1 %c, ptr %unknown) {265; OUNLM-LABEL: @non_matching_fp2(266; OUNLM-NEXT:    [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32267; OUNLM-NEXT:    [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloat, ptr [[UNKNOWN:%.*]]268; OUNLM-NEXT:    [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]269; OUNLM-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[FP]], @takeI32270; OUNLM-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]271; OUNLM:       2:272; OUNLM-NEXT:    call void @takeI32()273; OUNLM-NEXT:    br label [[TMP10:%.*]]274; OUNLM:       3:275; OUNLM-NEXT:    [[TMP4:%.*]] = icmp eq ptr [[FP]], @retI32276; OUNLM-NEXT:    br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]277; OUNLM:       5:278; OUNLM-NEXT:    call void @retI32()279; OUNLM-NEXT:    br label [[TMP10]]280; OUNLM:       6:281; OUNLM-NEXT:    [[TMP7:%.*]] = icmp eq ptr [[FP]], @retFloatTakeFloat282; OUNLM-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]283; OUNLM:       8:284; OUNLM-NEXT:    call void @retFloatTakeFloat()285; OUNLM-NEXT:    br label [[TMP10]]286; OUNLM:       9:287; OUNLM-NEXT:    call void [[FP]]()288; OUNLM-NEXT:    br label [[TMP10]]289; OUNLM:       10:290; OUNLM-NEXT:    ret void291;292; LIMI2-LABEL: @non_matching_fp2(293; LIMI2-NEXT:    [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32294; LIMI2-NEXT:    [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloat, ptr [[UNKNOWN:%.*]]295; LIMI2-NEXT:    [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]296; LIMI2-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[FP]], @takeI32297; LIMI2-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]298; LIMI2:       2:299; LIMI2-NEXT:    call void @takeI32()300; LIMI2-NEXT:    br label [[TMP7:%.*]]301; LIMI2:       3:302; LIMI2-NEXT:    [[TMP4:%.*]] = icmp eq ptr [[FP]], @retI32303; LIMI2-NEXT:    br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]304; LIMI2:       5:305; LIMI2-NEXT:    call void @retI32()306; LIMI2-NEXT:    br label [[TMP7]]307; LIMI2:       6:308; LIMI2-NEXT:    call void [[FP]]()309; LIMI2-NEXT:    br label [[TMP7]]310; LIMI2:       7:311; LIMI2-NEXT:    ret void312;313; LIMI0-LABEL: @non_matching_fp2(314; LIMI0-NEXT:    [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32315; LIMI0-NEXT:    [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloat, ptr [[UNKNOWN:%.*]]316; LIMI0-NEXT:    [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]317; LIMI0-NEXT:    call void [[FP]]()318; LIMI0-NEXT:    ret void319;320; CWRLD-LABEL: @non_matching_fp2(321; CWRLD-NEXT:    [[FP1:%.*]] = select i1 [[C1:%.*]], ptr @retI32, ptr @takeI32322; CWRLD-NEXT:    [[FP2:%.*]] = select i1 [[C2:%.*]], ptr @retFloatTakeFloat, ptr [[UNKNOWN:%.*]]323; CWRLD-NEXT:    [[FP:%.*]] = select i1 [[C:%.*]], ptr [[FP1]], ptr [[FP2]]324; CWRLD-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[FP]], @takeI32325; CWRLD-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]326; CWRLD:       2:327; CWRLD-NEXT:    call void @takeI32()328; CWRLD-NEXT:    br label [[TMP21:%.*]]329; CWRLD:       3:330; CWRLD-NEXT:    [[TMP4:%.*]] = icmp eq ptr [[FP]], @retI32331; CWRLD-NEXT:    br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]332; CWRLD:       5:333; CWRLD-NEXT:    call void @retI32()334; CWRLD-NEXT:    br label [[TMP21]]335; CWRLD:       6:336; CWRLD-NEXT:    [[TMP7:%.*]] = icmp eq ptr [[FP]], @func3337; CWRLD-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]338; CWRLD:       8:339; CWRLD-NEXT:    call void @func3()340; CWRLD-NEXT:    br label [[TMP21]]341; CWRLD:       9:342; CWRLD-NEXT:    [[TMP10:%.*]] = icmp eq ptr [[FP]], @func4343; CWRLD-NEXT:    br i1 [[TMP10]], label [[TMP11:%.*]], label [[TMP12:%.*]]344; CWRLD:       11:345; CWRLD-NEXT:    call void @func4()346; CWRLD-NEXT:    br label [[TMP21]]347; CWRLD:       12:348; CWRLD-NEXT:    [[TMP13:%.*]] = icmp eq ptr [[FP]], @retFloatTakeFloat349; CWRLD-NEXT:    br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP15:%.*]]350; CWRLD:       14:351; CWRLD-NEXT:    call void @retFloatTakeFloat()352; CWRLD-NEXT:    br label [[TMP21]]353; CWRLD:       15:354; CWRLD-NEXT:    [[TMP16:%.*]] = icmp eq ptr [[FP]], @retFloatTakeFloatFloatNoundef355; CWRLD-NEXT:    br i1 [[TMP16]], label [[TMP17:%.*]], label [[TMP18:%.*]]356; CWRLD:       17:357; CWRLD-NEXT:    call void @retFloatTakeFloatFloatNoundef()358; CWRLD-NEXT:    br label [[TMP21]]359; CWRLD:       18:360; CWRLD-NEXT:    br i1 true, label [[TMP19:%.*]], label [[TMP20:%.*]]361; CWRLD:       19:362; CWRLD-NEXT:    call void @void()363; CWRLD-NEXT:    br label [[TMP21]]364; CWRLD:       20:365; CWRLD-NEXT:    unreachable366; CWRLD:       21:367; CWRLD-NEXT:    ret void368;369  %fp1 = select i1 %c1, ptr @retI32, ptr @takeI32370  %fp2 = select i1 %c2, ptr @retFloatTakeFloat, ptr %unknown371  %fp = select i1 %c, ptr %fp1, ptr %fp2372  call void %fp()373  ret void374}375 376define i32 @non_matching_unknown(i1 %c, ptr %fn) {377; OUNLM-LABEL: @non_matching_unknown(378; OUNLM-NEXT:    [[FP:%.*]] = select i1 [[C:%.*]], ptr @retI32, ptr [[FN:%.*]]379; OUNLM-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[FP]], @retI32380; OUNLM-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]381; OUNLM:       2:382; OUNLM-NEXT:    [[CALL1:%.*]] = call i32 @retI32(i32 42)383; OUNLM-NEXT:    br label [[TMP4:%.*]]384; OUNLM:       3:385; OUNLM-NEXT:    [[CALL2:%.*]] = call i32 [[FP]](i32 42)386; OUNLM-NEXT:    br label [[TMP4]]387; OUNLM:       4:388; OUNLM-NEXT:    [[CALL_PHI:%.*]] = phi i32 [ [[CALL1]], [[TMP2]] ], [ [[CALL2]], [[TMP3]] ]389; OUNLM-NEXT:    ret i32 [[CALL_PHI]]390;391; LIMI2-LABEL: @non_matching_unknown(392; LIMI2-NEXT:    [[FP:%.*]] = select i1 [[C:%.*]], ptr @retI32, ptr [[FN:%.*]]393; LIMI2-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[FP]], @retI32394; LIMI2-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]395; LIMI2:       2:396; LIMI2-NEXT:    [[CALL1:%.*]] = call i32 @retI32(i32 42)397; LIMI2-NEXT:    br label [[TMP4:%.*]]398; LIMI2:       3:399; LIMI2-NEXT:    [[CALL2:%.*]] = call i32 [[FP]](i32 42)400; LIMI2-NEXT:    br label [[TMP4]]401; LIMI2:       4:402; LIMI2-NEXT:    [[CALL_PHI:%.*]] = phi i32 [ [[CALL1]], [[TMP2]] ], [ [[CALL2]], [[TMP3]] ]403; LIMI2-NEXT:    ret i32 [[CALL_PHI]]404;405; LIMI0-LABEL: @non_matching_unknown(406; LIMI0-NEXT:    [[FP:%.*]] = select i1 [[C:%.*]], ptr @retI32, ptr [[FN:%.*]]407; LIMI0-NEXT:    [[CALL:%.*]] = call i32 [[FP]](i32 42)408; LIMI0-NEXT:    ret i32 [[CALL]]409;410; CWRLD-LABEL: @non_matching_unknown(411; CWRLD-NEXT:    [[FP:%.*]] = select i1 [[C:%.*]], ptr @retI32, ptr [[FN:%.*]]412; CWRLD-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[FP]], @func3413; CWRLD-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]414; CWRLD:       2:415; CWRLD-NEXT:    [[CALL1:%.*]] = call i32 @func3(i32 42)416; CWRLD-NEXT:    br label [[TMP24:%.*]]417; CWRLD:       3:418; CWRLD-NEXT:    [[TMP4:%.*]] = icmp eq ptr [[FP]], @func4419; CWRLD-NEXT:    br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]420; CWRLD:       5:421; CWRLD-NEXT:    [[CALL2:%.*]] = call i32 @func4(i32 42)422; CWRLD-NEXT:    br label [[TMP24]]423; CWRLD:       6:424; CWRLD-NEXT:    [[TMP7:%.*]] = icmp eq ptr [[FP]], @retI32425; CWRLD-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]426; CWRLD:       8:427; CWRLD-NEXT:    [[CALL3:%.*]] = call i32 @retI32(i32 42)428; CWRLD-NEXT:    br label [[TMP24]]429; CWRLD:       9:430; CWRLD-NEXT:    [[TMP10:%.*]] = icmp eq ptr [[FP]], @takeI32431; CWRLD-NEXT:    br i1 [[TMP10]], label [[TMP11:%.*]], label [[TMP12:%.*]]432; CWRLD:       11:433; CWRLD-NEXT:    [[CALL4:%.*]] = call i32 @takeI32(i32 42)434; CWRLD-NEXT:    br label [[TMP24]]435; CWRLD:       12:436; CWRLD-NEXT:    [[TMP13:%.*]] = icmp eq ptr [[FP]], @retFloatTakeFloat437; CWRLD-NEXT:    br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP18:%.*]]438; CWRLD:       14:439; CWRLD-NEXT:    [[TMP15:%.*]] = bitcast i32 42 to float440; CWRLD-NEXT:    [[TMP16:%.*]] = call float @retFloatTakeFloat(float [[TMP15]])441; CWRLD-NEXT:    [[TMP17:%.*]] = bitcast float [[TMP16]] to i32442; CWRLD-NEXT:    br label [[TMP24]]443; CWRLD:       18:444; CWRLD-NEXT:    [[TMP19:%.*]] = icmp eq ptr [[FP]], @retFloatTakeFloatFloatNoundef445; CWRLD-NEXT:    br i1 [[TMP19]], label [[TMP20:%.*]], label [[TMP21:%.*]]446; CWRLD:       20:447; CWRLD-NEXT:    [[CALL5:%.*]] = call i32 @retFloatTakeFloatFloatNoundef(i32 42)448; CWRLD-NEXT:    br label [[TMP24]]449; CWRLD:       21:450; CWRLD-NEXT:    br i1 true, label [[TMP22:%.*]], label [[TMP23:%.*]]451; CWRLD:       22:452; CWRLD-NEXT:    [[CALL6:%.*]] = call i32 @void(i32 42)453; CWRLD-NEXT:    br label [[TMP24]]454; CWRLD:       23:455; CWRLD-NEXT:    unreachable456; CWRLD:       24:457; CWRLD-NEXT:    [[CALL_PHI:%.*]] = phi i32 [ [[CALL1]], [[TMP2]] ], [ [[CALL2]], [[TMP5]] ], [ [[CALL3]], [[TMP8]] ], [ [[CALL4]], [[TMP11]] ], [ [[TMP17]], [[TMP14]] ], [ [[CALL5]], [[TMP20]] ], [ [[CALL6]], [[TMP22]] ]458; CWRLD-NEXT:    ret i32 [[CALL_PHI]]459;460  %fp = select i1 %c, ptr @retI32, ptr %fn461  %call = call i32 %fp(i32 42)462  ret i32 %call463}464 465; This function is used in a "direct" call but with a different signature.466; We check that it does not show up above in any of the if-cascades because467; the address is not actually taken.468declare void @usedOnlyInCastedDirectCall(i32)469define void @usedOnlyInCastedDirectCallCaller() {470; CHECK-LABEL: @usedOnlyInCastedDirectCallCaller(471; CHECK-NEXT:    call void @usedOnlyInCastedDirectCall()472; CHECK-NEXT:    ret void473;474  call void @usedOnlyInCastedDirectCall()475  ret void476}477 478define internal void @usedByGlobal() {479; CHECK-LABEL: @usedByGlobal(480; CHECK-NEXT:    ret void481;482  ret void483}484@G = global ptr @usedByGlobal485 486define void @broker(ptr %unknown) !callback !0 {487; OWRDL-LABEL: @broker(488; OWRDL-NEXT:    call void [[UNKNOWN:%.*]]()489; OWRDL-NEXT:    ret void490;491; CWRLD-LABEL: @broker(492; CWRLD-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[UNKNOWN:%.*]], @func3493; CWRLD-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]494; CWRLD:       2:495; CWRLD-NEXT:    call void @func3()496; CWRLD-NEXT:    br label [[TMP21:%.*]]497; CWRLD:       3:498; CWRLD-NEXT:    [[TMP4:%.*]] = icmp eq ptr [[UNKNOWN]], @func4499; CWRLD-NEXT:    br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]500; CWRLD:       5:501; CWRLD-NEXT:    call void @func4()502; CWRLD-NEXT:    br label [[TMP21]]503; CWRLD:       6:504; CWRLD-NEXT:    [[TMP7:%.*]] = icmp eq ptr [[UNKNOWN]], @retI32505; CWRLD-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]506; CWRLD:       8:507; CWRLD-NEXT:    call void @retI32()508; CWRLD-NEXT:    br label [[TMP21]]509; CWRLD:       9:510; CWRLD-NEXT:    [[TMP10:%.*]] = icmp eq ptr [[UNKNOWN]], @takeI32511; CWRLD-NEXT:    br i1 [[TMP10]], label [[TMP11:%.*]], label [[TMP12:%.*]]512; CWRLD:       11:513; CWRLD-NEXT:    call void @takeI32()514; CWRLD-NEXT:    br label [[TMP21]]515; CWRLD:       12:516; CWRLD-NEXT:    [[TMP13:%.*]] = icmp eq ptr [[UNKNOWN]], @retFloatTakeFloat517; CWRLD-NEXT:    br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP15:%.*]]518; CWRLD:       14:519; CWRLD-NEXT:    call void @retFloatTakeFloat()520; CWRLD-NEXT:    br label [[TMP21]]521; CWRLD:       15:522; CWRLD-NEXT:    [[TMP16:%.*]] = icmp eq ptr [[UNKNOWN]], @retFloatTakeFloatFloatNoundef523; CWRLD-NEXT:    br i1 [[TMP16]], label [[TMP17:%.*]], label [[TMP18:%.*]]524; CWRLD:       17:525; CWRLD-NEXT:    call void @retFloatTakeFloatFloatNoundef()526; CWRLD-NEXT:    br label [[TMP21]]527; CWRLD:       18:528; CWRLD-NEXT:    br i1 true, label [[TMP19:%.*]], label [[TMP20:%.*]]529; CWRLD:       19:530; CWRLD-NEXT:    call void @void()531; CWRLD-NEXT:    br label [[TMP21]]532; CWRLD:       20:533; CWRLD-NEXT:    unreachable534; CWRLD:       21:535; CWRLD-NEXT:    ret void536;537  call void %unknown()538  ret void539}540 541define void @func6() {542; CHECK-LABEL: @func6(543; CHECK-NEXT:    call void @broker(ptr nofree noundef nonnull captures(none) @func3)544; CHECK-NEXT:    ret void545;546  call void @broker(ptr @func3)547  ret void548}549 550; Cannot be internal_good as it is internal and we see all uses.551; Can be func4 since it escapes.552define void @func7(ptr %unknown) {553; UPTO2-LABEL: @func7(554; UPTO2-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[UNKNOWN:%.*]], @func3555; UPTO2-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]556; UPTO2:       2:557; UPTO2-NEXT:    call void @func3()558; UPTO2-NEXT:    br label [[TMP6:%.*]]559; UPTO2:       3:560; UPTO2-NEXT:    br i1 true, label [[TMP4:%.*]], label [[TMP5:%.*]]561; UPTO2:       4:562; UPTO2-NEXT:    call void @func4()563; UPTO2-NEXT:    br label [[TMP6]]564; UPTO2:       5:565; UPTO2-NEXT:    unreachable566; UPTO2:       6:567; UPTO2-NEXT:    ret void568;569; LIMI0-LABEL: @func7(570; LIMI0-NEXT:    call void [[UNKNOWN:%.*]](), !callees [[META1]]571; LIMI0-NEXT:    ret void572;573  call void %unknown(), !callees !2574  ret void575}576 577; Check there's no crash if something that isn't a function appears in !callees578define void @undef_in_callees() {579; UNLIM-LABEL: @undef_in_callees(580; UNLIM-NEXT:  cond.end.i:581; UNLIM-NEXT:    call void undef(ptr undef, i32 undef, ptr undef), !callees [[META2:![0-9]+]]582; UNLIM-NEXT:    ret void583;584; LIMI2-LABEL: @undef_in_callees(585; LIMI2-NEXT:  cond.end.i:586; LIMI2-NEXT:    call void undef(ptr undef, i32 undef, ptr undef), !callees [[META4:![0-9]+]]587; LIMI2-NEXT:    ret void588;589; LIMI0-LABEL: @undef_in_callees(590; LIMI0-NEXT:  cond.end.i:591; LIMI0-NEXT:    call void undef(ptr undef, i32 undef, ptr undef), !callees [[META6:![0-9]+]]592; LIMI0-NEXT:    ret void593;594cond.end.i:595  call void undef(ptr undef, i32 undef, ptr undef), !callees !3596  ret void597}598 599define void @as_cast(ptr %arg) {600; OWRDL-LABEL: @as_cast(601; OWRDL-NEXT:    [[FP:%.*]] = load ptr addrspace(1), ptr [[ARG:%.*]], align 8602; OWRDL-NEXT:    tail call addrspace(1) void [[FP]]()603; OWRDL-NEXT:    ret void604;605; CWRLD-LABEL: @as_cast(606; CWRLD-NEXT:    [[FP:%.*]] = load ptr addrspace(1), ptr [[ARG:%.*]], align 8607; CWRLD-NEXT:    [[FP_AS0:%.*]] = addrspacecast ptr addrspace(1) [[FP]] to ptr608; CWRLD-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[FP_AS0]], @func3609; CWRLD-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]610; CWRLD:       2:611; CWRLD-NEXT:    tail call void @func3()612; CWRLD-NEXT:    br label [[TMP21:%.*]]613; CWRLD:       3:614; CWRLD-NEXT:    [[TMP4:%.*]] = icmp eq ptr [[FP_AS0]], @func4615; CWRLD-NEXT:    br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]616; CWRLD:       5:617; CWRLD-NEXT:    tail call void @func4()618; CWRLD-NEXT:    br label [[TMP21]]619; CWRLD:       6:620; CWRLD-NEXT:    [[TMP7:%.*]] = icmp eq ptr [[FP_AS0]], @retI32621; CWRLD-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]622; CWRLD:       8:623; CWRLD-NEXT:    call void @retI32()624; CWRLD-NEXT:    br label [[TMP21]]625; CWRLD:       9:626; CWRLD-NEXT:    [[TMP10:%.*]] = icmp eq ptr [[FP_AS0]], @takeI32627; CWRLD-NEXT:    br i1 [[TMP10]], label [[TMP11:%.*]], label [[TMP12:%.*]]628; CWRLD:       11:629; CWRLD-NEXT:    call void @takeI32()630; CWRLD-NEXT:    br label [[TMP21]]631; CWRLD:       12:632; CWRLD-NEXT:    [[TMP13:%.*]] = icmp eq ptr [[FP_AS0]], @retFloatTakeFloat633; CWRLD-NEXT:    br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP15:%.*]]634; CWRLD:       14:635; CWRLD-NEXT:    call void @retFloatTakeFloat()636; CWRLD-NEXT:    br label [[TMP21]]637; CWRLD:       15:638; CWRLD-NEXT:    [[TMP16:%.*]] = icmp eq ptr [[FP_AS0]], @retFloatTakeFloatFloatNoundef639; CWRLD-NEXT:    br i1 [[TMP16]], label [[TMP17:%.*]], label [[TMP18:%.*]]640; CWRLD:       17:641; CWRLD-NEXT:    call void @retFloatTakeFloatFloatNoundef()642; CWRLD-NEXT:    br label [[TMP21]]643; CWRLD:       18:644; CWRLD-NEXT:    br i1 true, label [[TMP19:%.*]], label [[TMP20:%.*]]645; CWRLD:       19:646; CWRLD-NEXT:    tail call void @void()647; CWRLD-NEXT:    br label [[TMP21]]648; CWRLD:       20:649; CWRLD-NEXT:    unreachable650; CWRLD:       21:651; CWRLD-NEXT:    ret void652;653  %fp = load ptr addrspace(1), ptr %arg, align 8654  tail call addrspace(1) void %fp()655  ret void656}657 658!0 = !{!1}659!1 = !{i64 0, i1 false}660!2 = !{ptr @func3, ptr @func4}661!3 = distinct !{ptr undef, ptr null}662 663; UTC_ARGS: --disable664 665; DOT-DAG: Node[[FUNC1:0x[a-z0-9]+]] [shape=record,label="{func1}"];666; DOT-DAG: Node[[FUNC2:0x[a-z0-9]+]] [shape=record,label="{func2}"];667; DOT-DAG: Node[[FUNC3:0x[a-z0-9]+]] [shape=record,label="{func3}"];668; DOT-DAG: Node[[FUNC4:0x[a-z0-9]+]] [shape=record,label="{func4}"];669; DOT-DAG: Node[[FUNC5:0x[a-z0-9]+]] [shape=record,label="{func5}"];670; DOT-DAG: Node[[FUNC6:0x[a-z0-9]+]] [shape=record,label="{func6}"];671; DOT-DAG: Node[[FUNC7:0x[a-z0-9]+]] [shape=record,label="{func7}"];672 673; DOT-DAG: Node[[BROKER:0x[a-z0-9]+]] [shape=record,label="{broker}"];674 675; DOT-DAG: Node[[FUNC1]] -> Node[[FUNC3]];676; DOT-DAG: Node[[FUNC2]] -> Node[[FUNC4]];677; DOT-DAG: Node[[FUNC5]] -> Node[[FUNC3]];678; DOT-DAG: Node[[FUNC5]] -> Node[[FUNC4]];679 680; DOT-DAG: Node[[FUNC6]] -> Node[[BROKER]];681 682; This one gets added because of the callback metadata.683; DOT-DAG: Node[[FUNC6]] -> Node[[FUNC3]];684 685; These ones are added because of the callees metadata.686; DOT-DAG: Node[[FUNC7]] -> Node[[FUNC3]];687; DOT-DAG: Node[[FUNC7]] -> Node[[FUNC4]];688 689; UTC_ARGS: --enable690 691;.692; OUNLM: attributes #[[ATTR0:[0-9]+]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }693;.694; LIMI2: attributes #[[ATTR0:[0-9]+]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }695;.696; LIMI0: attributes #[[ATTR0:[0-9]+]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }697;.698; CWRLD: attributes #[[ATTR0:[0-9]+]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }699;.700; OUNLM: [[META0:![0-9]+]] = !{[[META1:![0-9]+]]}701; OUNLM: [[META1]] = !{i64 0, i1 false}702; OUNLM: [[META2]] = distinct !{ptr undef, ptr null}703;.704; LIMI2: [[META0]] = !{ptr @void, ptr @retFloatTakeFloat}705; LIMI2: [[META1]] = !{ptr @void}706; LIMI2: [[META2:![0-9]+]] = !{[[META3:![0-9]+]]}707; LIMI2: [[META3]] = !{i64 0, i1 false}708; LIMI2: [[META4]] = distinct !{ptr undef, ptr null}709;.710; LIMI0: [[META0]] = !{ptr @func4, ptr @internal_good}711; LIMI0: [[META1]] = !{ptr @func3, ptr @func4}712; LIMI0: [[META2]] = !{ptr @takeI32, ptr @retI32, ptr @void, ptr @retFloatTakeFloat}713; LIMI0: [[META3]] = !{ptr @takeI32, ptr @retI32, ptr @void}714; LIMI0: [[META4:![0-9]+]] = !{[[META5:![0-9]+]]}715; LIMI0: [[META5]] = !{i64 0, i1 false}716; LIMI0: [[META6]] = distinct !{ptr undef, ptr null}717;.718; CWRLD: [[META0:![0-9]+]] = !{[[META1:![0-9]+]]}719; CWRLD: [[META1]] = !{i64 0, i1 false}720; CWRLD: [[META2]] = distinct !{ptr undef, ptr null}721;.722;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:723; DOT: {{.*}}724