1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; Verify that calls to memrchr with arrays of elements larger than char 3; are folded correctly. 4; RUN: opt < %s -passes=instcombine -S -data-layout="E" | FileCheck %s --check-prefixes=BE 5; RUN: opt < %s -passes=instcombine -S -data-layout="e" | FileCheck %s --check-prefixes=LE 6 7declare ptr @memrchr(ptr, i32, i64) 8 9; BE representation: { 'a', 'b', 'c', 'd', 'e', ..., 'p', 'a', 'b', 'c', 'd' } 10; LE representation: { 'd', 'c', 'b', 'a', 'h', ..., 'm', 'd', 'c', 'b', 'a' } 11@a = constant [5 x i32] [i32 1633837924, i32 1701209960, i32 1768581996, i32 1835954032, i32 1633837924] 12 13 14; Fold memrchr(a, C, 16) for C in ['a', 'd'] U ['o', 'q']. 15 16define void @fold_memrchr_a_16(ptr %pcmp) { 17; BE-LABEL: @fold_memrchr_a_16( 18; BE-NEXT: store i64 0, ptr [[PCMP:%.*]], align 4 19; BE-NEXT: [[PSTOR1:%.*]] = getelementptr i8, ptr [[PCMP]], i64 8 20; BE-NEXT: store i64 1, ptr [[PSTOR1]], align 4 21; BE-NEXT: [[PSTOR2:%.*]] = getelementptr i8, ptr [[PCMP]], i64 16 22; BE-NEXT: store i64 2, ptr [[PSTOR2]], align 4 23; BE-NEXT: [[PSTOR3:%.*]] = getelementptr i8, ptr [[PCMP]], i64 24 24; BE-NEXT: store i64 3, ptr [[PSTOR3]], align 4 25; BE-NEXT: [[PSTOR4:%.*]] = getelementptr i8, ptr [[PCMP]], i64 32 26; BE-NEXT: store i64 13, ptr [[PSTOR4]], align 4 27; BE-NEXT: [[PSTOR6:%.*]] = getelementptr i8, ptr [[PCMP]], i64 48 28; BE-NEXT: store i64 14, ptr [[PSTOR6]], align 4 29; BE-NEXT: [[PSTOR7:%.*]] = getelementptr i8, ptr [[PCMP]], i64 56 30; BE-NEXT: store i64 15, ptr [[PSTOR7]], align 4 31; BE-NEXT: [[PSTOR8:%.*]] = getelementptr i8, ptr [[PCMP]], i64 64 32; BE-NEXT: store i64 0, ptr [[PSTOR8]], align 4 33; BE-NEXT: ret void 34; 35; LE-LABEL: @fold_memrchr_a_16( 36; LE-NEXT: store i64 3, ptr [[PCMP:%.*]], align 4 37; LE-NEXT: [[PSTOR1:%.*]] = getelementptr i8, ptr [[PCMP]], i64 8 38; LE-NEXT: store i64 2, ptr [[PSTOR1]], align 4 39; LE-NEXT: [[PSTOR2:%.*]] = getelementptr i8, ptr [[PCMP]], i64 16 40; LE-NEXT: store i64 1, ptr [[PSTOR2]], align 4 41; LE-NEXT: [[PSTOR3:%.*]] = getelementptr i8, ptr [[PCMP]], i64 24 42; LE-NEXT: store i64 0, ptr [[PSTOR3]], align 4 43; LE-NEXT: [[PSTOR4:%.*]] = getelementptr i8, ptr [[PCMP]], i64 32 44; LE-NEXT: store i64 14, ptr [[PSTOR4]], align 4 45; LE-NEXT: [[PSTOR6:%.*]] = getelementptr i8, ptr [[PCMP]], i64 48 46; LE-NEXT: store i64 13, ptr [[PSTOR6]], align 4 47; LE-NEXT: [[PSTOR7:%.*]] = getelementptr i8, ptr [[PCMP]], i64 56 48; LE-NEXT: store i64 12, ptr [[PSTOR7]], align 4 49; LE-NEXT: [[PSTOR8:%.*]] = getelementptr i8, ptr [[PCMP]], i64 64 50; LE-NEXT: store i64 0, ptr [[PSTOR8]], align 4 51; LE-NEXT: ret void 52; 53 %ip0 = ptrtoint ptr @a to i64 54 55; Fold memrchr(a, 'a', 16) - a to 0 (3 in LE). 56 57 %pa = call ptr @memrchr(ptr @a, i32 97, i64 16) 58 %ipa = ptrtoint ptr %pa to i64 59 %offa = sub i64 %ipa, %ip0 60 store i64 %offa, ptr %pcmp 61 62; Fold memrchr(a, 'b', 16) - a to 1 (2 in LE) 63 64 %pb = call ptr @memrchr(ptr @a, i32 98, i64 16) 65 %ipb = ptrtoint ptr %pb to i64 66 %offb = sub i64 %ipb, %ip0 67 %pstor1 = getelementptr i64, ptr %pcmp, i64 1 68 store i64 %offb, ptr %pstor1 69 70; Fold memrchr(a, 'c', 16) - a to 2 (1 in LE) 71 72 %pc = call ptr @memrchr(ptr @a, i32 99, i64 16) 73 %ipc = ptrtoint ptr %pc to i64 74 %offc = sub i64 %ipc, %ip0 75 %pstor2 = getelementptr i64, ptr %pcmp, i64 2 76 store i64 %offc, ptr %pstor2 77 78; Fold memrchr(a, 'd', 16) - a to 3 (0 in LE) 79 80 %pd = call ptr @memrchr(ptr @a, i32 100, i64 16) 81 %ipd = ptrtoint ptr %pd to i64 82 %offd = sub i64 %ipd, %ip0 83 %pstor3 = getelementptr i64, ptr %pcmp, i64 3 84 store i64 %offd, ptr %pstor3 85 86; Fold memrchr(a, 'n', 16) - a to 13 (14 in LE) 87 88 %pn = call ptr @memrchr(ptr @a, i32 110, i64 16) 89 %ipn = ptrtoint ptr %pn to i64 90 %offn = sub i64 %ipn, %ip0 91 %pstor4 = getelementptr i64, ptr %pcmp, i64 4 92 store i64 %offn, ptr %pstor4 93 94; Fold memrchr(a, 'o', 16) - a to 14 (13 in LE) 95 96 %po = call ptr @memrchr(ptr @a, i32 111, i64 16) 97 %ipo = ptrtoint ptr %po to i64 98 %offo = sub i64 %ipo, %ip0 99 %pstor6 = getelementptr i64, ptr %pcmp, i64 6 100 store i64 %offo, ptr %pstor6 101 102; Fold memrchr(a, 'p', 16) - a to 15 (12 in LE) 103 104 %pp = call ptr @memrchr(ptr @a, i32 112, i64 16) 105 %ipp = ptrtoint ptr %pp to i64 106 %offp = sub i64 %ipp, %ip0 107 %pstor7 = getelementptr i64, ptr %pcmp, i64 7 108 store i64 %offp, ptr %pstor7 109 110; Fold memrchr(a, 'q', 16) to null in both BE and LE. 111 112 %pq = call ptr @memrchr(ptr @a, i32 113, i64 16) 113 %ipq = ptrtoint ptr %pq to i64 114 %pstor8 = getelementptr i64, ptr %pcmp, i64 8 115 store i64 %ipq, ptr %pstor8 116 117 ret void 118} 119 120 121; Fold memrchr(a + 1, C, 12) for C in ['e', 'h'] U ['a', 'd']. 122 123define void @fold_memrchr_a_p1_16(ptr %pcmp) { 124; BE-LABEL: @fold_memrchr_a_p1_16( 125; BE-NEXT: store i64 0, ptr [[PCMP:%.*]], align 4 126; BE-NEXT: [[PSTOR1:%.*]] = getelementptr i8, ptr [[PCMP]], i64 8 127; BE-NEXT: store i64 1, ptr [[PSTOR1]], align 4 128; BE-NEXT: [[PSTOR2:%.*]] = getelementptr i8, ptr [[PCMP]], i64 16 129; BE-NEXT: store i64 2, ptr [[PSTOR2]], align 4 130; BE-NEXT: [[PSTOR3:%.*]] = getelementptr i8, ptr [[PCMP]], i64 24 131; BE-NEXT: store i64 3, ptr [[PSTOR3]], align 4 132; BE-NEXT: [[PSTOR4:%.*]] = getelementptr i8, ptr [[PCMP]], i64 32 133; BE-NEXT: store i64 0, ptr [[PSTOR4]], align 4 134; BE-NEXT: [[PSTOR5:%.*]] = getelementptr i8, ptr [[PCMP]], i64 40 135; BE-NEXT: store i64 0, ptr [[PSTOR5]], align 4 136; BE-NEXT: ret void 137; 138; LE-LABEL: @fold_memrchr_a_p1_16( 139; LE-NEXT: store i64 3, ptr [[PCMP:%.*]], align 4 140; LE-NEXT: [[PSTOR1:%.*]] = getelementptr i8, ptr [[PCMP]], i64 8 141; LE-NEXT: store i64 2, ptr [[PSTOR1]], align 4 142; LE-NEXT: [[PSTOR2:%.*]] = getelementptr i8, ptr [[PCMP]], i64 16 143; LE-NEXT: store i64 1, ptr [[PSTOR2]], align 4 144; LE-NEXT: [[PSTOR3:%.*]] = getelementptr i8, ptr [[PCMP]], i64 24 145; LE-NEXT: store i64 0, ptr [[PSTOR3]], align 4 146; LE-NEXT: [[PSTOR4:%.*]] = getelementptr i8, ptr [[PCMP]], i64 32 147; LE-NEXT: store i64 0, ptr [[PSTOR4]], align 4 148; LE-NEXT: [[PSTOR5:%.*]] = getelementptr i8, ptr [[PCMP]], i64 40 149; LE-NEXT: store i64 0, ptr [[PSTOR5]], align 4 150; LE-NEXT: ret void 151; 152 %p0 = getelementptr [5 x i32], ptr @a, i64 0, i64 1 153 %ip0 = ptrtoint ptr %p0 to i64 154 155; Fold memrchr(a + 1, 'e', 12) - a to 0 (3 in LE). 156 157 %pe = call ptr @memrchr(ptr %p0, i32 101, i64 12) 158 %ipe = ptrtoint ptr %pe to i64 159 %offe = sub i64 %ipe, %ip0 160 store i64 %offe, ptr %pcmp 161 162; Fold memrchr(a + 1, 'f', 12) - a to 1 (2 in LE). 163 164 %pf = call ptr @memrchr(ptr %p0, i32 102, i64 12) 165 %ipf = ptrtoint ptr %pf to i64 166 %offf = sub i64 %ipf, %ip0 167 %pstor1 = getelementptr i64, ptr %pcmp, i64 1 168 store i64 %offf, ptr %pstor1 169 170; Fold memrchr(a + 1, 'g', 12) - a to 2 (1 in LE). 171 172 %pg = call ptr @memrchr(ptr %p0, i32 103, i64 12) 173 %ipg = ptrtoint ptr %pg to i64 174 %offg = sub i64 %ipg, %ip0 175 %pstor2 = getelementptr i64, ptr %pcmp, i64 2 176 store i64 %offg, ptr %pstor2 177 178; Fold memrchr(a + 1, 'h', 12) - a to 3 (0 in LE). 179 180 %ph = call ptr @memrchr(ptr %p0, i32 104, i64 12) 181 %iph = ptrtoint ptr %ph to i64 182 %offh = sub i64 %iph, %ip0 183 %pstor3 = getelementptr i64, ptr %pcmp, i64 3 184 store i64 %offh, ptr %pstor3 185 186; Fold memrchr(a + 1, 'a', 12) to null in both BE and LE. 187 188 %pa = call ptr @memrchr(ptr %p0, i32 97, i64 12) 189 %ipa = ptrtoint ptr %pa to i64 190 %pstor4 = getelementptr i64, ptr %pcmp, i64 4 191 store i64 %ipa, ptr %pstor4 192 193; Fold memrchr(a + 1, 'd', 12) to null in both BE and LE. 194 195 %pd = call ptr @memrchr(ptr %p0, i32 100, i64 12) 196 %ipd = ptrtoint ptr %pd to i64 197 %pstor5 = getelementptr i64, ptr %pcmp, i64 5 198 store i64 %ipd, ptr %pstor5 199 200 ret void 201} 202 203 204; Fold memrchr(a, C, 20) for C in ['a', 'e']. 205 206define void @fold_memrchr_a_20(ptr %pcmp) { 207; BE-LABEL: @fold_memrchr_a_20( 208; BE-NEXT: store i64 16, ptr [[PCMP:%.*]], align 4 209; BE-NEXT: [[PSTOR1:%.*]] = getelementptr i8, ptr [[PCMP]], i64 8 210; BE-NEXT: store i64 17, ptr [[PSTOR1]], align 4 211; BE-NEXT: [[PSTOR2:%.*]] = getelementptr i8, ptr [[PCMP]], i64 16 212; BE-NEXT: store i64 18, ptr [[PSTOR2]], align 4 213; BE-NEXT: [[PSTOR3:%.*]] = getelementptr i8, ptr [[PCMP]], i64 24 214; BE-NEXT: store i64 19, ptr [[PSTOR3]], align 4 215; BE-NEXT: [[PSTOR4:%.*]] = getelementptr i8, ptr [[PCMP]], i64 32 216; BE-NEXT: store i64 4, ptr [[PSTOR4]], align 4 217; BE-NEXT: ret void 218; 219; LE-LABEL: @fold_memrchr_a_20( 220; LE-NEXT: store i64 19, ptr [[PCMP:%.*]], align 4 221; LE-NEXT: [[PSTOR1:%.*]] = getelementptr i8, ptr [[PCMP]], i64 8 222; LE-NEXT: store i64 18, ptr [[PSTOR1]], align 4 223; LE-NEXT: [[PSTOR2:%.*]] = getelementptr i8, ptr [[PCMP]], i64 16 224; LE-NEXT: store i64 17, ptr [[PSTOR2]], align 4 225; LE-NEXT: [[PSTOR3:%.*]] = getelementptr i8, ptr [[PCMP]], i64 24 226; LE-NEXT: store i64 16, ptr [[PSTOR3]], align 4 227; LE-NEXT: [[PSTOR4:%.*]] = getelementptr i8, ptr [[PCMP]], i64 32 228; LE-NEXT: store i64 7, ptr [[PSTOR4]], align 4 229; LE-NEXT: ret void 230; 231 %ip0 = ptrtoint ptr @a to i64 232 233; Fold memrchr(a, 'a', 20) - a to 16 (19 in LE). 234 235 %pa = call ptr @memrchr(ptr @a, i32 97, i64 20) 236 %ipa = ptrtoint ptr %pa to i64 237 %offa = sub i64 %ipa, %ip0 238 store i64 %offa, ptr %pcmp 239 240; Fold memrchr(a, 'b', 16) - a to 17 (18 in LE) 241 242 %pb = call ptr @memrchr(ptr @a, i32 98, i64 20) 243 %ipb = ptrtoint ptr %pb to i64 244 %offb = sub i64 %ipb, %ip0 245 %pstor1 = getelementptr i64, ptr %pcmp, i64 1 246 store i64 %offb, ptr %pstor1 247 248; Fold memrchr(a, 'c', 16) - a to 18 (17 in LE) 249 250 %pc = call ptr @memrchr(ptr @a, i32 99, i64 20) 251 %ipc = ptrtoint ptr %pc to i64 252 %offc = sub i64 %ipc, %ip0 253 %pstor2 = getelementptr i64, ptr %pcmp, i64 2 254 store i64 %offc, ptr %pstor2 255 256; Fold memrchr(a, 'd', 16) - a to 19 (16 in LE) 257 258 %pd = call ptr @memrchr(ptr @a, i32 100, i64 20) 259 %ipd = ptrtoint ptr %pd to i64 260 %offd = sub i64 %ipd, %ip0 261 %pstor3 = getelementptr i64, ptr %pcmp, i64 3 262 store i64 %offd, ptr %pstor3 263 264; Fold memrchr(a, 'e', 16) - a to 4 (7 in LE) 265 266 %pe = call ptr @memrchr(ptr @a, i32 101, i64 20) 267 %ipe = ptrtoint ptr %pe to i64 268 %offe = sub i64 %ipe, %ip0 269 %pstor4 = getelementptr i64, ptr %pcmp, i64 4 270 store i64 %offe, ptr %pstor4 271 272 ret void 273} 274