117 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 62; RUN: opt < %s -passes=sccp -S | FileCheck %s3 4define i1 @relax_range_check(i8 range(i8 0, 5) %x) {5; CHECK-LABEL: define i1 @relax_range_check(6; CHECK-SAME: i8 range(i8 0, 5) [[X:%.*]]) {7; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X]], -38; CHECK-NEXT: [[RET:%.*]] = icmp uge i8 [[X]], 39; CHECK-NEXT: ret i1 [[RET]]10;11 %add = add i8 %x, -312 %ret = icmp ult i8 %add, 213 ret i1 %ret14}15 16define i1 @relax_range_check_highbits_check(i8 range(i8 2, 0) %x) {17; CHECK-LABEL: define i1 @relax_range_check_highbits_check(18; CHECK-SAME: i8 range(i8 2, 0) [[X:%.*]]) {19; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -220; CHECK-NEXT: [[RET:%.*]] = icmp ult i8 [[X]], 421; CHECK-NEXT: ret i1 [[RET]]22;23 %and = and i8 %x, -224 %ret = icmp eq i8 %and, 225 ret i1 %ret26}27 28; Negative tests.29 30define i1 @relax_range_check_one_instruction(i8 range(i8 0, 5) %x) {31; CHECK-LABEL: define i1 @relax_range_check_one_instruction(32; CHECK-SAME: i8 range(i8 0, 5) [[X:%.*]]) {33; CHECK-NEXT: [[RET:%.*]] = icmp ult i8 [[X]], 234; CHECK-NEXT: ret i1 [[RET]]35;36 %ret = icmp ult i8 %x, 237 ret i1 %ret38}39 40define i1 @relax_range_check_not_profitable(i8 range(i8 0, 6) %x) {41; CHECK-LABEL: define i1 @relax_range_check_not_profitable(42; CHECK-SAME: i8 range(i8 0, 6) [[X:%.*]]) {43; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X]], -344; CHECK-NEXT: [[RET:%.*]] = icmp ult i8 [[ADD]], 245; CHECK-NEXT: ret i1 [[RET]]46;47 %add = add i8 %x, -348 %ret = icmp ult i8 %add, 249 ret i1 %ret50}51 52define i1 @relax_range_check_unknown_range(i64 %x) {53; CHECK-LABEL: define i1 @relax_range_check_unknown_range(54; CHECK-SAME: i64 [[X:%.*]]) {55; CHECK-NEXT: [[AND:%.*]] = and i64 [[X]], -6710886456; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[AND]], 057; CHECK-NEXT: ret i1 [[TMP1]]58;59 %and = and i64 %x, -6710886460 %test = icmp eq i64 %and, 061 ret i1 %test62}63 64define i1 @relax_range_check_highbits_check_multiuse(i8 range(i8 2, 0) %x) {65; CHECK-LABEL: define i1 @relax_range_check_highbits_check_multiuse(66; CHECK-SAME: i8 range(i8 2, 0) [[X:%.*]]) {67; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -268; CHECK-NEXT: call void @use(i8 [[AND]])69; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[AND]], 270; CHECK-NEXT: ret i1 [[RET]]71;72 %and = and i8 %x, -273 call void @use(i8 %and)74 %ret = icmp eq i8 %and, 275 ret i1 %ret76}77 78define i1 @relax_range_check_multiuse(i8 range(i8 0, 5) %x) {79; CHECK-LABEL: define i1 @relax_range_check_multiuse(80; CHECK-SAME: i8 range(i8 0, 5) [[X:%.*]]) {81; CHECK-NEXT: [[ADD:%.*]] = add nsw i8 [[X]], -382; CHECK-NEXT: call void @use(i8 [[ADD]])83; CHECK-NEXT: [[RET:%.*]] = icmp ult i8 [[ADD]], 284; CHECK-NEXT: ret i1 [[RET]]85;86 %add = add i8 %x, -387 call void @use(i8 %add)88 %ret = icmp ult i8 %add, 289 ret i1 %ret90}91 92define i1 @range_check_to_icmp_eq1(i32 range(i32 0, 4) %x) {93; CHECK-LABEL: define i1 @range_check_to_icmp_eq1(94; CHECK-SAME: i32 range(i32 0, 4) [[X:%.*]]) {95; CHECK-NEXT: [[OFF:%.*]] = add nsw i32 [[X]], -396; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X]], 397; CHECK-NEXT: ret i1 [[TMP1]]98;99 %off = add nsw i32 %x, -3100 %cmp = icmp ult i32 %off, 2101 ret i1 %cmp102}103 104define i1 @range_check_to_icmp_eq2(i32 range(i32 -1, 2) %x) {105; CHECK-LABEL: define i1 @range_check_to_icmp_eq2(106; CHECK-SAME: i32 range(i32 -1, 2) [[X:%.*]]) {107; CHECK-NEXT: [[OFF:%.*]] = add nsw i32 [[X]], -1108; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], 1109; CHECK-NEXT: ret i1 [[CMP]]110;111 %off = add nsw i32 %x, -1112 %cmp = icmp ult i32 %off, -2113 ret i1 %cmp114}115 116declare void @use(i8)117