1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=ipsccp -S | FileCheck %s --check-prefixes=CHECK,IPSCCP 3; RUN: opt < %s -passes=sccp -S | FileCheck %s --check-prefixes=CHECK,SCCP 4 5declare void @use(i1) 6declare i32 @get_i32() 7 8define void @range_attribute(i32 range(i32 0, 10) %v) { 9; CHECK-LABEL: @range_attribute( 10; CHECK-NEXT: call void @use(i1 true) 11; CHECK-NEXT: [[C2:%.*]] = icmp ult i32 [[V:%.*]], 9 12; CHECK-NEXT: call void @use(i1 [[C2]]) 13; CHECK-NEXT: call void @use(i1 false) 14; CHECK-NEXT: [[C4:%.*]] = icmp ugt i32 [[V]], 8 15; CHECK-NEXT: call void @use(i1 [[C4]]) 16; CHECK-NEXT: ret void 17; 18 %c1 = icmp ult i32 %v, 10 19 call void @use(i1 %c1) 20 %c2 = icmp ult i32 %v, 9 21 call void @use(i1 %c2) 22 %c3 = icmp ugt i32 %v, 9 23 call void @use(i1 %c3) 24 %c4 = icmp ugt i32 %v, 8 25 call void @use(i1 %c4) 26 ret void 27} 28 29define i32 @range_attribute_single(i32 range(i32 0, 1) %v) { 30; IPSCCP-LABEL: @range_attribute_single( 31; IPSCCP-NEXT: ret i32 0 32; 33; SCCP-LABEL: @range_attribute_single( 34; SCCP-NEXT: ret i32 [[V:%.*]] 35; 36 ret i32 %v 37} 38 39define void @call_range_attribute() { 40; CHECK-LABEL: @call_range_attribute( 41; CHECK-NEXT: [[V:%.*]] = call range(i32 0, 10) i32 @get_i32() 42; CHECK-NEXT: call void @use(i1 true) 43; CHECK-NEXT: [[C2:%.*]] = icmp ult i32 [[V]], 9 44; CHECK-NEXT: call void @use(i1 [[C2]]) 45; CHECK-NEXT: call void @use(i1 false) 46; CHECK-NEXT: [[C4:%.*]] = icmp ugt i32 [[V]], 8 47; CHECK-NEXT: call void @use(i1 [[C4]]) 48; CHECK-NEXT: ret void 49; 50 %v = call range(i32 0, 10) i32 @get_i32() 51 %c1 = icmp ult i32 %v, 10 52 call void @use(i1 %c1) 53 %c2 = icmp ult i32 %v, 9 54 call void @use(i1 %c2) 55 %c3 = icmp ugt i32 %v, 9 56 call void @use(i1 %c3) 57 %c4 = icmp ugt i32 %v, 8 58 call void @use(i1 %c4) 59 ret void 60} 61 62 63declare range(i32 0, 10) i32 @get_i32_in_range() 64 65define void @call_range_result() { 66; CHECK-LABEL: @call_range_result( 67; CHECK-NEXT: [[V:%.*]] = call i32 @get_i32_in_range() 68; CHECK-NEXT: call void @use(i1 true) 69; CHECK-NEXT: [[C2:%.*]] = icmp ult i32 [[V]], 9 70; CHECK-NEXT: call void @use(i1 [[C2]]) 71; CHECK-NEXT: call void @use(i1 false) 72; CHECK-NEXT: [[C4:%.*]] = icmp ugt i32 [[V]], 8 73; CHECK-NEXT: call void @use(i1 [[C4]]) 74; CHECK-NEXT: ret void 75; 76 %v = call i32 @get_i32_in_range() 77 %c1 = icmp ult i32 %v, 10 78 call void @use(i1 %c1) 79 %c2 = icmp ult i32 %v, 9 80 call void @use(i1 %c2) 81 %c3 = icmp ugt i32 %v, 9 82 call void @use(i1 %c3) 83 %c4 = icmp ugt i32 %v, 8 84 call void @use(i1 %c4) 85 ret void 86} 87 88define internal i1 @ip_cmp_range_attribute(i32 %v) { 89; IPSCCP-LABEL: @ip_cmp_range_attribute( 90; IPSCCP-NEXT: ret i1 poison 91; 92; SCCP-LABEL: @ip_cmp_range_attribute( 93; SCCP-NEXT: [[C:%.*]] = icmp ult i32 [[V:%.*]], 10 94; SCCP-NEXT: ret i1 [[C]] 95; 96 %c = icmp ult i32 %v, 10 97 ret i1 %c 98} 99 100define i1 @ip_range_attribute(i32 range(i32 0, 10) %v) { 101; IPSCCP-LABEL: @ip_range_attribute( 102; IPSCCP-NEXT: [[C:%.*]] = call i1 @ip_cmp_range_attribute(i32 [[V:%.*]]) 103; IPSCCP-NEXT: ret i1 true 104; 105; SCCP-LABEL: @ip_range_attribute( 106; SCCP-NEXT: [[C:%.*]] = call i1 @ip_cmp_range_attribute(i32 [[V:%.*]]) 107; SCCP-NEXT: ret i1 [[C]] 108; 109 %c = call i1 @ip_cmp_range_attribute(i32 %v) 110 ret i1 %c 111} 112 113define internal i1 @ip_cmp_range_call(i32 %v) { 114; IPSCCP-LABEL: @ip_cmp_range_call( 115; IPSCCP-NEXT: ret i1 poison 116; 117; SCCP-LABEL: @ip_cmp_range_call( 118; SCCP-NEXT: [[C:%.*]] = icmp ult i32 [[V:%.*]], 10 119; SCCP-NEXT: ret i1 [[C]] 120; 121 %c = icmp ult i32 %v, 10 122 ret i1 %c 123} 124 125define i1 @ip_range_call() { 126; IPSCCP-LABEL: @ip_range_call( 127; IPSCCP-NEXT: [[V:%.*]] = call range(i32 0, 10) i32 @get_i32() 128; IPSCCP-NEXT: [[C:%.*]] = call i1 @ip_cmp_range_call(i32 [[V]]) 129; IPSCCP-NEXT: ret i1 true 130; 131; SCCP-LABEL: @ip_range_call( 132; SCCP-NEXT: [[V:%.*]] = call range(i32 0, 10) i32 @get_i32() 133; SCCP-NEXT: [[C:%.*]] = call i1 @ip_cmp_range_call(i32 [[V]]) 134; SCCP-NEXT: ret i1 [[C]] 135; 136 %v = call range(i32 0, 10) i32 @get_i32() 137 %c = call i1 @ip_cmp_range_call(i32 %v) 138 ret i1 %c 139} 140 141define internal i1 @ip_cmp_range_result(i32 %v) { 142; IPSCCP-LABEL: @ip_cmp_range_result( 143; IPSCCP-NEXT: ret i1 poison 144; 145; SCCP-LABEL: @ip_cmp_range_result( 146; SCCP-NEXT: [[C:%.*]] = icmp ult i32 [[V:%.*]], 10 147; SCCP-NEXT: ret i1 [[C]] 148; 149 %c = icmp ult i32 %v, 10 150 ret i1 %c 151} 152 153define i1 @ip_range_result() { 154; IPSCCP-LABEL: @ip_range_result( 155; IPSCCP-NEXT: [[V:%.*]] = call range(i32 0, 10) i32 @get_i32() 156; IPSCCP-NEXT: [[C:%.*]] = call i1 @ip_cmp_range_result(i32 [[V]]) 157; IPSCCP-NEXT: ret i1 true 158; 159; SCCP-LABEL: @ip_range_result( 160; SCCP-NEXT: [[V:%.*]] = call range(i32 0, 10) i32 @get_i32() 161; SCCP-NEXT: [[C:%.*]] = call i1 @ip_cmp_range_result(i32 [[V]]) 162; SCCP-NEXT: ret i1 [[C]] 163; 164 %v = call range(i32 0, 10) i32 @get_i32() 165 %c = call i1 @ip_cmp_range_result(i32 %v) 166 ret i1 %c 167} 168 169define internal i1 @ip_cmp_with_range_attribute(i32 range(i32 0, 10) %v) { 170; IPSCCP-LABEL: @ip_cmp_with_range_attribute( 171; IPSCCP-NEXT: ret i1 poison 172; 173; SCCP-LABEL: @ip_cmp_with_range_attribute( 174; SCCP-NEXT: [[C:%.*]] = icmp eq i32 [[V:%.*]], 5 175; SCCP-NEXT: ret i1 [[C]] 176; 177 %c = icmp eq i32 %v, 5 178 ret i1 %c 179} 180 181define i1 @ip_range_attribute_constant() { 182; IPSCCP-LABEL: @ip_range_attribute_constant( 183; IPSCCP-NEXT: [[C:%.*]] = call i1 @ip_cmp_with_range_attribute(i32 5) 184; IPSCCP-NEXT: ret i1 true 185; 186; SCCP-LABEL: @ip_range_attribute_constant( 187; SCCP-NEXT: [[C:%.*]] = call i1 @ip_cmp_with_range_attribute(i32 5) 188; SCCP-NEXT: ret i1 [[C]] 189; 190 %c = call i1 @ip_cmp_with_range_attribute(i32 5) 191 ret i1 %c 192} 193 194define internal i1 @ip_cmp_attribute_overdefined_callee(i32 range(i32 0, 10) %x) { 195; IPSCCP-LABEL: @ip_cmp_attribute_overdefined_callee( 196; IPSCCP-NEXT: ret i1 poison 197; 198; SCCP-LABEL: @ip_cmp_attribute_overdefined_callee( 199; SCCP-NEXT: ret i1 true 200; 201 %cmp = icmp ult i32 %x, 10 202 ret i1 %cmp 203} 204 205define i1 @ip_cmp_attribute_overdefined_caller(i32 %x) { 206; IPSCCP-LABEL: @ip_cmp_attribute_overdefined_caller( 207; IPSCCP-NEXT: [[RES:%.*]] = call i1 @ip_cmp_attribute_overdefined_callee(i32 [[X:%.*]]) 208; IPSCCP-NEXT: ret i1 true 209; 210; SCCP-LABEL: @ip_cmp_attribute_overdefined_caller( 211; SCCP-NEXT: [[RES:%.*]] = call i1 @ip_cmp_attribute_overdefined_callee(i32 [[X:%.*]]) 212; SCCP-NEXT: ret i1 [[RES]] 213; 214 %res = call i1 @ip_cmp_attribute_overdefined_callee(i32 %x) 215 ret i1 %res 216} 217 218define internal i1 @ip_cmp_attribute_intersect_callee(i32 range(i32 0, 10) %x) { 219; IPSCCP-LABEL: @ip_cmp_attribute_intersect_callee( 220; IPSCCP-NEXT: ret i1 poison 221; 222; SCCP-LABEL: @ip_cmp_attribute_intersect_callee( 223; SCCP-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X:%.*]], 5 224; SCCP-NEXT: [[AND:%.*]] = and i1 true, [[CMP2]] 225; SCCP-NEXT: ret i1 [[AND]] 226; 227 %cmp1 = icmp ult i32 %x, 10 228 %cmp2 = icmp uge i32 %x, 5 229 %and = and i1 %cmp1, %cmp2 230 ret i1 %and 231} 232 233define i1 @ip_cmp_attribute_intersect_caller(i32 range(i32 5, 15) %x) { 234; IPSCCP-LABEL: @ip_cmp_attribute_intersect_caller( 235; IPSCCP-NEXT: [[RES:%.*]] = call i1 @ip_cmp_attribute_intersect_callee(i32 [[X:%.*]]) 236; IPSCCP-NEXT: ret i1 true 237; 238; SCCP-LABEL: @ip_cmp_attribute_intersect_caller( 239; SCCP-NEXT: [[RES:%.*]] = call i1 @ip_cmp_attribute_intersect_callee(i32 [[X:%.*]]) 240; SCCP-NEXT: ret i1 [[RES]] 241; 242 %res = call i1 @ip_cmp_attribute_intersect_callee(i32 %x) 243 ret i1 %res 244} 245