1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 3 4define i1 @gep0_and_cmp(ptr readonly %src, ptr readnone %min, ptr readnone %max) { 5; CHECK-LABEL: @gep0_and_cmp( 6; CHECK-NEXT: check.0.min: 7; CHECK-NEXT: [[SRC_C:%.*]] = getelementptr i32, ptr [[SRC:%.*]], i64 0 8; CHECK-NEXT: [[MIN_C:%.*]] = getelementptr i32, ptr [[MIN:%.*]], i64 0 9; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 3 10; CHECK-NEXT: [[GEP_3_C:%.*]] = getelementptr i32, ptr [[GEP_3]], i32 0 11; CHECK-NEXT: [[C_MIN_0:%.*]] = icmp ult ptr [[SRC_C]], [[MIN_C]] 12; CHECK-NEXT: [[C_MAX_3:%.*]] = icmp ugt ptr [[GEP_3_C]], [[MAX:%.*]] 13; CHECK-NEXT: [[OR:%.*]] = or i1 [[C_MIN_0]], [[C_MAX_3]] 14; CHECK-NEXT: br i1 [[OR]], label [[TRAP:%.*]], label [[CHECKS:%.*]] 15; CHECK: trap: 16; CHECK-NEXT: ret i1 false 17; CHECK: checks: 18; CHECK-NEXT: [[C_3_MAX:%.*]] = icmp ult ptr [[GEP_3]], [[MAX]] 19; CHECK-NEXT: [[RES_1:%.*]] = xor i1 false, [[C_3_MAX]] 20; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 1 21; CHECK-NEXT: [[RES_2:%.*]] = xor i1 false, true 22; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 2 23; CHECK-NEXT: [[RES_3:%.*]] = xor i1 false, true 24; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 4 25; CHECK-NEXT: [[C_4_MAX:%.*]] = icmp ult ptr [[GEP_4]], [[MAX]] 26; CHECK-NEXT: [[RES_4:%.*]] = xor i1 false, [[C_4_MAX]] 27; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_1]], [[RES_2]] 28; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[RES_3]] 29; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[RES_4]] 30; CHECK-NEXT: ret i1 [[RES_7]] 31; 32check.0.min: 33 %src.c = getelementptr i32, ptr %src, i64 0 34 %min.c = getelementptr i32, ptr %min, i64 0 35 36 %gep.3 = getelementptr inbounds i32, ptr %src, i64 3 37 %gep.3.c = getelementptr i32, ptr %gep.3, i32 0 38 %c.min.0 = icmp ult ptr %src.c, %min.c 39 %c.max.3 = icmp ugt ptr %gep.3.c, %max 40 41 %or = or i1 %c.min.0, %c.max.3 42 br i1 %or, label %trap, label %checks 43 44trap: 45 ret i1 0 46 47checks: 48 %c.3.min = icmp ult ptr %gep.3, %min 49 %c.3.max = icmp ult ptr %gep.3, %max 50 %res.1 = xor i1 %c.3.min, %c.3.max 51 52 %gep.1 = getelementptr inbounds i32, ptr %src, i64 1 53 %c.1.min = icmp ult ptr %gep.1, %min 54 %c.1.max = icmp ult ptr %gep.1, %max 55 %res.2 = xor i1 %c.1.min, %c.1.max 56 57 %gep.2 = getelementptr inbounds i32, ptr %src, i64 2 58 %c.2.min = icmp ult ptr %gep.2, %min 59 %c.2.max = icmp ult ptr %gep.2, %max 60 %res.3 = xor i1 %c.2.min, %c.2.max 61 62 %gep.4 = getelementptr inbounds i32, ptr %src, i64 4 63 %c.4.min = icmp ult ptr %gep.4, %min 64 %c.4.max = icmp ult ptr %gep.4, %max 65 %res.4 = xor i1 %c.4.min, %c.4.max 66 67 %res.5 = xor i1 %res.1, %res.2 68 %res.6 = xor i1 %res.5, %res.3 69 %res.7 = xor i1 %res.6, %res.4 70 71 ret i1 %res.7 72} 73 74; Should not look through addresspacecast, because it may change the pointer 75; value. 76define i1 @addrspacecast_and_cmp(ptr readonly %src, ptr readnone %min, ptr readnone %max) { 77; CHECK-LABEL: @addrspacecast_and_cmp( 78; CHECK-NEXT: check.0.min: 79; CHECK-NEXT: [[SRC_C:%.*]] = addrspacecast ptr [[SRC:%.*]] to ptr addrspace(1) 80; CHECK-NEXT: [[MIN_C:%.*]] = addrspacecast ptr [[MIN:%.*]] to ptr addrspace(1) 81; CHECK-NEXT: [[MAX_C:%.*]] = addrspacecast ptr [[MAX:%.*]] to ptr addrspace(1) 82; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 3 83; CHECK-NEXT: [[GEP_3_C:%.*]] = addrspacecast ptr [[GEP_3]] to ptr addrspace(1) 84; CHECK-NEXT: [[C_MIN_0:%.*]] = icmp ult ptr addrspace(1) [[SRC_C]], [[MIN_C]] 85; CHECK-NEXT: [[C_MAX_3:%.*]] = icmp ugt ptr addrspace(1) [[GEP_3_C]], [[MAX_C]] 86; CHECK-NEXT: [[OR:%.*]] = or i1 [[C_MIN_0]], [[C_MAX_3]] 87; CHECK-NEXT: br i1 [[OR]], label [[TRAP:%.*]], label [[CHECKS:%.*]] 88; CHECK: trap: 89; CHECK-NEXT: ret i1 false 90; CHECK: checks: 91; CHECK-NEXT: [[C_3_MIN:%.*]] = icmp ult ptr [[GEP_3]], [[MIN]] 92; CHECK-NEXT: [[C_3_MAX:%.*]] = icmp ult ptr [[GEP_3]], [[MAX]] 93; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[C_3_MIN]], [[C_3_MAX]] 94; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 1 95; CHECK-NEXT: [[C_1_MIN:%.*]] = icmp ult ptr [[GEP_1]], [[MIN]] 96; CHECK-NEXT: [[C_1_MAX:%.*]] = icmp ult ptr [[GEP_1]], [[MAX]] 97; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[C_1_MIN]], [[C_1_MAX]] 98; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 2 99; CHECK-NEXT: [[C_2_MIN:%.*]] = icmp ult ptr [[GEP_2]], [[MIN]] 100; CHECK-NEXT: [[C_2_MAX:%.*]] = icmp ult ptr [[GEP_2]], [[MAX]] 101; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[C_2_MIN]], [[C_2_MAX]] 102; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 4 103; CHECK-NEXT: [[C_4_MIN:%.*]] = icmp ult ptr [[GEP_4]], [[MIN]] 104; CHECK-NEXT: [[C_4_MAX:%.*]] = icmp ult ptr [[GEP_4]], [[MAX]] 105; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[C_4_MIN]], [[C_4_MAX]] 106; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_1]], [[RES_2]] 107; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[RES_3]] 108; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[RES_4]] 109; CHECK-NEXT: ret i1 [[RES_7]] 110; 111check.0.min: 112 %src.c = addrspacecast ptr %src to ptr addrspace(1) 113 %min.c = addrspacecast ptr %min to ptr addrspace(1) 114 %max.c = addrspacecast ptr %max to ptr addrspace(1) 115 116 %gep.3 = getelementptr inbounds i32, ptr %src, i64 3 117 %gep.3.c = addrspacecast ptr %gep.3 to ptr addrspace(1) 118 %c.min.0 = icmp ult ptr addrspace(1) %src.c, %min.c 119 %c.max.3 = icmp ugt ptr addrspace(1) %gep.3.c, %max.c 120 121 %or = or i1 %c.min.0, %c.max.3 122 br i1 %or, label %trap, label %checks 123 124trap: 125 ret i1 0 126 127checks: 128 %c.3.min = icmp ult ptr %gep.3, %min 129 %c.3.max = icmp ult ptr %gep.3, %max 130 %res.1 = xor i1 %c.3.min, %c.3.max 131 132 %gep.1 = getelementptr inbounds i32, ptr %src, i64 1 133 %c.1.min = icmp ult ptr %gep.1, %min 134 %c.1.max = icmp ult ptr %gep.1, %max 135 %res.2 = xor i1 %c.1.min, %c.1.max 136 137 %gep.2 = getelementptr inbounds i32, ptr %src, i64 2 138 %c.2.min = icmp ult ptr %gep.2, %min 139 %c.2.max = icmp ult ptr %gep.2, %max 140 %res.3 = xor i1 %c.2.min, %c.2.max 141 142 %gep.4 = getelementptr inbounds i32, ptr %src, i64 4 143 %c.4.min = icmp ult ptr %gep.4, %min 144 %c.4.max = icmp ult ptr %gep.4, %max 145 %res.4 = xor i1 %c.4.min, %c.4.max 146 147 %res.5 = xor i1 %res.1, %res.2 148 %res.6 = xor i1 %res.5, %res.3 149 %res.7 = xor i1 %res.6, %res.4 150 151 ret i1 %res.7 152} 153