1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt -passes=ipsccp -S %s | FileCheck %s 3 4; Test 1. 5; Both arguments and return value of @callee can be tracked. The inferred range 6; can be added to call sites. 7define internal i32 @callee(i32 %x) { 8; CHECK-LABEL: define internal range(i32 0, 21) i32 @callee( 9; CHECK-SAME: i32 range(i32 0, 21) [[X:%.*]]) { 10; CHECK-NEXT: ret i32 [[X]] 11; 12 ret i32 %x 13} 14 15define i32 @caller1() { 16; CHECK-LABEL: define range(i32 0, 41) i32 @caller1() { 17; CHECK-NEXT: [[C1:%.*]] = call i32 @callee(i32 10) 18; CHECK-NEXT: [[C2:%.*]] = call i32 @callee(i32 20) 19; CHECK-NEXT: [[A:%.*]] = add nuw nsw i32 [[C1]], [[C2]] 20; CHECK-NEXT: ret i32 [[A]] 21; 22 %c1 = call i32 @callee(i32 10) 23 %c2 = call i32 @callee(i32 20) 24 %a = add i32 %c1, %c2 25 ret i32 %a 26} 27 28define i32 @caller2(i32 %x) { 29; CHECK-LABEL: define range(i32 0, 21) i32 @caller2( 30; CHECK-SAME: i32 [[X:%.*]]) { 31; CHECK-NEXT: [[X_15:%.*]] = and i32 [[X]], 15 32; CHECK-NEXT: [[C:%.*]] = call i32 @callee(i32 [[X_15]]) 33; CHECK-NEXT: ret i32 [[C]] 34; 35 %x.15 = and i32 %x, 15 36 %c = call i32 @callee(i32 %x.15) 37 ret i32 %c 38} 39 40; Test 2. 41; The return value of @callee2 can be tracked, but arguments cannot, because 42; it is passed to @use_cb1. We cannot infer a range for the return value, no 43; metadata should be added. 44 45declare void @use_cb1(ptr) 46 47define internal i32 @callee2(i32 %x) { 48; CHECK-LABEL: define internal i32 @callee2( 49; CHECK-SAME: i32 [[X:%.*]]) { 50; CHECK-NEXT: ret i32 [[X]] 51; 52 ret i32 %x 53} 54 55define void @caller_cb1() { 56; CHECK-LABEL: define void @caller_cb1() { 57; CHECK-NEXT: [[C1:%.*]] = call i32 @callee2(i32 9) 58; CHECK-NEXT: [[C2:%.*]] = call i32 @callee2(i32 10) 59; CHECK-NEXT: call void @use_cb1(ptr @callee2) 60; CHECK-NEXT: ret void 61; 62 %c1 = call i32 @callee2(i32 9) 63 %c2 = call i32 @callee2(i32 10) 64 call void @use_cb1(ptr @callee2) 65 ret void 66} 67 68; Test 3. 69; The return value can be tracked and it the result range ([500, 601) does not 70; depend on the arguments, which cannot be tracked because @callee3 is passed 71; to @use_cb2. The result range can be added to the call sites of @callee. 72 73declare void @use_cb2(ptr) 74 75define internal i32 @callee3(i32 %x) { 76; CHECK-LABEL: define internal range(i32 500, 601) i32 @callee3( 77; CHECK-SAME: i32 [[X:%.*]]) { 78; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X]], 10 79; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 500, i32 600 80; CHECK-NEXT: ret i32 [[S]] 81; 82 %c = icmp eq i32 %x, 10 83 %s = select i1 %c, i32 500, i32 600 84 ret i32 %s 85} 86 87define void @caller_cb2() { 88; CHECK-LABEL: define void @caller_cb2() { 89; CHECK-NEXT: [[C1:%.*]] = call i32 @callee3(i32 9) 90; CHECK-NEXT: [[C2:%.*]] = call i32 @callee3(i32 10) 91; CHECK-NEXT: call void @use_cb2(ptr @callee3) 92; CHECK-NEXT: ret void 93; 94 %c1 = call i32 @callee3(i32 9) 95 %c2 = call i32 @callee3(i32 10) 96 call void @use_cb2(ptr @callee3) 97 ret void 98} 99 100; Test 4. 101; The return value of @callee4 can be tracked, but depends on an argument which 102; cannot be tracked. No result range can be inferred. 103 104declare void @use_cb3(ptr) 105 106define internal i32 @callee4(i32 %x, i32 %y) { 107; CHECK-LABEL: define internal i32 @callee4( 108; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { 109; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X]], 10 110; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 500, i32 [[Y]] 111; CHECK-NEXT: ret i32 [[S]] 112; 113 %c = icmp eq i32 %x, 10 114 %s = select i1 %c, i32 500, i32 %y 115 ret i32 %s 116} 117 118define void @caller_cb3() { 119; CHECK-LABEL: define void @caller_cb3() { 120; CHECK-NEXT: [[C1:%.*]] = call i32 @callee4(i32 11, i32 30) 121; CHECK-NEXT: [[C2:%.*]] = call i32 @callee4(i32 12, i32 40) 122; CHECK-NEXT: call void @use_cb3(ptr @callee4) 123; CHECK-NEXT: ret void 124; 125 %c1 = call i32 @callee4(i32 11, i32 30) 126 %c2 = call i32 @callee4(i32 12, i32 40) 127 call void @use_cb3(ptr @callee4) 128 ret void 129} 130 131; Test 5. 132; Range for the return value of callee5 includes undef. No range metadata 133; should be added at call sites. 134define internal i32 @callee5(i32 %x, i32 %y) { 135; CHECK-LABEL: define internal i32 @callee5( 136; CHECK-SAME: i32 range(i32 10, 21) [[X:%.*]], i32 range(i32 100, 201) [[Y:%.*]]) { 137; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[X]], 15 138; CHECK-NEXT: br i1 [[C]], label [[BB1:%.*]], label [[BB2:%.*]] 139; CHECK: bb1: 140; CHECK-NEXT: br label [[EXIT:%.*]] 141; CHECK: bb2: 142; CHECK-NEXT: br label [[EXIT]] 143; CHECK: exit: 144; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[Y]], [[BB1]] ], [ undef, [[BB2]] ] 145; CHECK-NEXT: ret i32 [[RES]] 146; 147 %c = icmp slt i32 %x, 15 148 br i1 %c, label %bb1, label %bb2 149 150bb1: 151 br label %exit 152 153bb2: 154 br label %exit 155 156exit: 157 %res = phi i32 [ %y, %bb1 ], [ undef, %bb2] 158 ret i32 %res 159} 160 161define i32 @caller5() { 162; CHECK-LABEL: define i32 @caller5() { 163; CHECK-NEXT: [[C1:%.*]] = call i32 @callee5(i32 10, i32 100) 164; CHECK-NEXT: [[C2:%.*]] = call i32 @callee5(i32 20, i32 200) 165; CHECK-NEXT: [[A:%.*]] = add i32 [[C1]], [[C2]] 166; CHECK-NEXT: ret i32 [[A]] 167; 168 %c1 = call i32 @callee5(i32 10, i32 100) 169 %c2 = call i32 @callee5(i32 20, i32 200) 170 %a = add i32 %c1, %c2 171 ret i32 %a 172} 173 174define internal <2 x i64> @ctlz(<2 x i64> %arg) { 175; CHECK-LABEL: define internal range(i64 0, 65) <2 x i64> @ctlz( 176; CHECK-SAME: <2 x i64> [[ARG:%.*]]) { 177; CHECK-NEXT: [[RES:%.*]] = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> [[ARG]], i1 false) 178; CHECK-NEXT: ret <2 x i64> [[RES]] 179; 180 %res = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %arg, i1 false) 181 ret <2 x i64> %res 182} 183 184define <2 x i64> @ctlz_caller(<2 x i64> %arg) { 185; CHECK-LABEL: define range(i64 0, 65) <2 x i64> @ctlz_caller( 186; CHECK-SAME: <2 x i64> [[ARG:%.*]]) { 187; CHECK-NEXT: [[RES:%.*]] = call <2 x i64> @ctlz(<2 x i64> [[ARG]]) 188; CHECK-NEXT: ret <2 x i64> [[RES]] 189; 190 %res = call <2 x i64> @ctlz(<2 x i64> %arg) 191 ret <2 x i64> %res 192} 193 194declare <2 x i64> @llvm.ctlz.v2i64(<2 x i64>, i1) 195 196