1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=ipsccp -S | FileCheck %s 3 4declare void @use(i1) 5declare i32 @get_i32() 6 7define void @load_range(ptr %p) { 8; CHECK-LABEL: @load_range( 9; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4, !range [[RNG0:![0-9]+]] 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 %v = load i32, ptr %p, !range !{i32 0, i32 10} 19 %c1 = icmp ult i32 %v, 10 20 call void @use(i1 %c1) 21 %c2 = icmp ult i32 %v, 9 22 call void @use(i1 %c2) 23 %c3 = icmp ugt i32 %v, 9 24 call void @use(i1 %c3) 25 %c4 = icmp ugt i32 %v, 8 26 call void @use(i1 %c4) 27 ret void 28} 29 30define i32 @load_range_single(ptr %p) { 31; CHECK-LABEL: @load_range_single( 32; CHECK-NEXT: ret i32 0 33; 34 %v = load i32, ptr %p, !range !{i32 0, i32 1} 35 ret i32 %v 36} 37 38define i32 @load_range_single_volatile(ptr %p) { 39; CHECK-LABEL: @load_range_single_volatile( 40; CHECK-NEXT: [[V:%.*]] = load volatile i32, ptr [[P:%.*]], align 4, !range [[RNG1:![0-9]+]] 41; CHECK-NEXT: ret i32 [[V]] 42; 43 %v = load volatile i32, ptr %p, !range !{i32 0, i32 1} 44 ret i32 %v 45} 46 47define void @load_nonnull(ptr %p, ptr %p2) { 48; CHECK-LABEL: @load_nonnull( 49; CHECK-NEXT: [[V:%.*]] = load ptr, ptr [[P:%.*]], align 8, !nonnull [[META2:![0-9]+]] 50; CHECK-NEXT: [[V2:%.*]] = load ptr, ptr [[P2:%.*]], align 8, !nonnull [[META2]] 51; CHECK-NEXT: call void @use(i1 true) 52; CHECK-NEXT: call void @use(i1 false) 53; CHECK-NEXT: call void @use(i1 true) 54; CHECK-NEXT: call void @use(i1 false) 55; CHECK-NEXT: [[C5:%.*]] = icmp eq ptr [[V]], [[V2]] 56; CHECK-NEXT: call void @use(i1 [[C5]]) 57; CHECK-NEXT: [[C6:%.*]] = icmp ne ptr [[V]], [[V2]] 58; CHECK-NEXT: call void @use(i1 [[C6]]) 59; CHECK-NEXT: ret void 60; 61 %v = load ptr, ptr %p, !nonnull !{} 62 %v2 = load ptr, ptr %p2, !nonnull !{} 63 %c1 = icmp ne ptr %v, null 64 call void @use(i1 %c1) 65 %c2 = icmp eq ptr %v, null 66 call void @use(i1 %c2) 67 %c3 = icmp ne ptr null, %v 68 call void @use(i1 %c3) 69 %c4 = icmp eq ptr null, %v 70 call void @use(i1 %c4) 71 ; There is no particular relationship between two nonnull values. 72 %c5 = icmp eq ptr %v, %v2 73 call void @use(i1 %c5) 74 %c6 = icmp ne ptr %v, %v2 75 call void @use(i1 %c6) 76 ret void 77} 78 79define void @call_range(ptr %p) { 80; CHECK-LABEL: @call_range( 81; CHECK-NEXT: [[V:%.*]] = call i32 @get_i32(), !range [[RNG0]] 82; CHECK-NEXT: call void @use(i1 true) 83; CHECK-NEXT: [[C2:%.*]] = icmp ult i32 [[V]], 9 84; CHECK-NEXT: call void @use(i1 [[C2]]) 85; CHECK-NEXT: call void @use(i1 false) 86; CHECK-NEXT: [[C4:%.*]] = icmp ugt i32 [[V]], 8 87; CHECK-NEXT: call void @use(i1 [[C4]]) 88; CHECK-NEXT: ret void 89; 90 %v = call i32 @get_i32(), !range !{i32 0, i32 10} 91 %c1 = icmp ult i32 %v, 10 92 call void @use(i1 %c1) 93 %c2 = icmp ult i32 %v, 9 94 call void @use(i1 %c2) 95 %c3 = icmp ugt i32 %v, 9 96 call void @use(i1 %c3) 97 %c4 = icmp ugt i32 %v, 8 98 call void @use(i1 %c4) 99 ret void 100} 101 102define internal i1 @ip_cmp_range(i32 %v) { 103; CHECK-LABEL: @ip_cmp_range( 104; CHECK-NEXT: ret i1 poison 105; 106 %c = icmp ult i32 %v, 10 107 ret i1 %c 108} 109 110define i1 @ip_load_range(ptr %p) { 111; CHECK-LABEL: @ip_load_range( 112; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4, !range [[RNG0]] 113; CHECK-NEXT: [[C:%.*]] = call i1 @ip_cmp_range(i32 [[V]]) 114; CHECK-NEXT: ret i1 true 115; 116 %v = load i32, ptr %p, !range !{i32 0, i32 10} 117 %c = call i1 @ip_cmp_range(i32 %v) 118 ret i1 %c 119} 120