1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 2; RUN: opt -S -mcpu=gfx900 -amdgpu-lower-buffer-fat-pointers < %s | FileCheck %s 3; RUN: opt -S -mcpu=gfx900 -passes=amdgpu-lower-buffer-fat-pointers < %s | FileCheck %s 4 5target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8" 6target triple = "amdgcn--" 7 8define ptr addrspace(7) @gep(ptr addrspace(7) %in, i32 %idx) { 9; CHECK-LABEL: define { ptr addrspace(8), i32 } @gep 10; CHECK-SAME: ({ ptr addrspace(8), i32 } [[IN:%.*]], i32 [[IDX:%.*]]) #[[ATTR0:[0-9]+]] { 11; CHECK-NEXT: [[IN_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[IN]], 0 12; CHECK-NEXT: [[IN_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[IN]], 1 13; CHECK-NEXT: [[RET_IDX:%.*]] = mul nsw i32 [[IDX]], 40 14; CHECK-NEXT: [[RET_OFFS:%.*]] = add nsw i32 [[RET_IDX]], 8 15; CHECK-NEXT: [[RET_OFFS1:%.*]] = add nsw i32 [[RET_OFFS]], 24 16; CHECK-NEXT: [[RET:%.*]] = add i32 [[IN_OFF]], [[RET_OFFS1]] 17; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[IN_RSRC]], 0 18; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP1]], i32 [[RET]], 1 19; CHECK-NEXT: ret { ptr addrspace(8), i32 } [[TMP2]] 20; 21 %ret = getelementptr inbounds {i32, [4 x ptr]}, ptr addrspace(7) %in, i32 %idx, i32 1, i32 3 22 ret ptr addrspace(7) %ret 23} 24 25define <2 x ptr addrspace(7)> @gep_vectors(<2 x ptr addrspace(7)> %in, <2 x i32> %idx) { 26; CHECK-LABEL: define { <2 x ptr addrspace(8)>, <2 x i32> } @gep_vectors 27; CHECK-SAME: ({ <2 x ptr addrspace(8)>, <2 x i32> } [[IN:%.*]], <2 x i32> [[IDX:%.*]]) #[[ATTR0]] { 28; CHECK-NEXT: [[IN_RSRC:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[IN]], 0 29; CHECK-NEXT: [[IN_OFF:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[IN]], 1 30; CHECK-NEXT: [[RET_IDX:%.*]] = mul nsw <2 x i32> [[IDX]], splat (i32 40) 31; CHECK-NEXT: [[RET_OFFS:%.*]] = add nsw <2 x i32> [[RET_IDX]], splat (i32 8) 32; CHECK-NEXT: [[RET_OFFS1:%.*]] = add nsw <2 x i32> [[RET_OFFS]], splat (i32 24) 33; CHECK-NEXT: [[RET:%.*]] = add <2 x i32> [[IN_OFF]], [[RET_OFFS1]] 34; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { <2 x ptr addrspace(8)>, <2 x i32> } poison, <2 x ptr addrspace(8)> [[IN_RSRC]], 0 35; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[TMP1]], <2 x i32> [[RET]], 1 36; CHECK-NEXT: ret { <2 x ptr addrspace(8)>, <2 x i32> } [[TMP2]] 37; 38 %ret = getelementptr inbounds {i32, [4 x ptr]}, <2 x ptr addrspace(7)> %in, <2 x i32> %idx, i32 1, i32 3 39 ret <2 x ptr addrspace(7)> %ret 40} 41 42define <2 x ptr addrspace(7)> @gep_vector_scalar(<2 x ptr addrspace(7)> %in, i64 %idx) { 43; CHECK-LABEL: define { <2 x ptr addrspace(8)>, <2 x i32> } @gep_vector_scalar 44; CHECK-SAME: ({ <2 x ptr addrspace(8)>, <2 x i32> } [[IN:%.*]], i64 [[IDX:%.*]]) #[[ATTR0]] { 45; CHECK-NEXT: [[IN_RSRC:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[IN]], 0 46; CHECK-NEXT: [[IN_OFF:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[IN]], 1 47; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[IDX]], i64 0 48; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <2 x i64> [[DOTSPLATINSERT]], <2 x i64> poison, <2 x i32> zeroinitializer 49; CHECK-NEXT: [[DOTSPLAT_C:%.*]] = trunc <2 x i64> [[DOTSPLAT]] to <2 x i32> 50; CHECK-NEXT: [[RET_IDX:%.*]] = mul nsw <2 x i32> [[DOTSPLAT_C]], splat (i32 40) 51; CHECK-NEXT: [[RET_OFFS:%.*]] = add nsw <2 x i32> [[RET_IDX]], splat (i32 8) 52; CHECK-NEXT: [[RET_OFFS1:%.*]] = add nsw <2 x i32> [[RET_OFFS]], splat (i32 24) 53; CHECK-NEXT: [[RET:%.*]] = add <2 x i32> [[IN_OFF]], [[RET_OFFS1]] 54; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { <2 x ptr addrspace(8)>, <2 x i32> } poison, <2 x ptr addrspace(8)> [[IN_RSRC]], 0 55; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[TMP1]], <2 x i32> [[RET]], 1 56; CHECK-NEXT: ret { <2 x ptr addrspace(8)>, <2 x i32> } [[TMP2]] 57; 58 %ret = getelementptr inbounds {i32, [4 x ptr]}, <2 x ptr addrspace(7)> %in, i64 %idx, i32 1, i32 3 59 ret <2 x ptr addrspace(7)> %ret 60} 61 62define ptr addrspace(7) @simple_gep(ptr addrspace(7) %ptr, i32 %off) { 63; CHECK-LABEL: define { ptr addrspace(8), i32 } @simple_gep 64; CHECK-SAME: ({ ptr addrspace(8), i32 } [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] { 65; CHECK-NEXT: [[PTR_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 0 66; CHECK-NEXT: [[PTR_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 1 67; CHECK-NEXT: [[RET_IDX:%.*]] = mul i32 [[OFF]], 4 68; CHECK-NEXT: [[RET:%.*]] = add i32 [[PTR_OFF]], [[RET_IDX]] 69; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[PTR_RSRC]], 0 70; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP1]], i32 [[RET]], 1 71; CHECK-NEXT: ret { ptr addrspace(8), i32 } [[TMP2]] 72; 73 %ret = getelementptr i32, ptr addrspace(7) %ptr, i32 %off 74 ret ptr addrspace(7) %ret 75} 76 77define ptr addrspace(7) @simple_inbounds_gep(ptr addrspace(7) %ptr, i32 %off) { 78; CHECK-LABEL: define { ptr addrspace(8), i32 } @simple_inbounds_gep 79; CHECK-SAME: ({ ptr addrspace(8), i32 } [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] { 80; CHECK-NEXT: [[PTR_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 0 81; CHECK-NEXT: [[PTR_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 1 82; CHECK-NEXT: [[RET_IDX:%.*]] = mul nsw i32 [[OFF]], 4 83; CHECK-NEXT: [[RET:%.*]] = add i32 [[PTR_OFF]], [[RET_IDX]] 84; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[PTR_RSRC]], 0 85; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP1]], i32 [[RET]], 1 86; CHECK-NEXT: ret { ptr addrspace(8), i32 } [[TMP2]] 87; 88 %ret = getelementptr inbounds i32, ptr addrspace(7) %ptr, i32 %off 89 ret ptr addrspace(7) %ret 90} 91 92define ptr addrspace(7) @simple_nuw_gep(ptr addrspace(7) %ptr, i32 %off) { 93; CHECK-LABEL: define { ptr addrspace(8), i32 } @simple_nuw_gep 94; CHECK-SAME: ({ ptr addrspace(8), i32 } [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] { 95; CHECK-NEXT: [[PTR_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 0 96; CHECK-NEXT: [[PTR_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 1 97; CHECK-NEXT: [[RET_IDX:%.*]] = mul nuw i32 [[OFF]], 4 98; CHECK-NEXT: [[RET:%.*]] = add nuw i32 [[PTR_OFF]], [[RET_IDX]] 99; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[PTR_RSRC]], 0 100; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP1]], i32 [[RET]], 1 101; CHECK-NEXT: ret { ptr addrspace(8), i32 } [[TMP2]] 102; 103 %ret = getelementptr nuw i32, ptr addrspace(7) %ptr, i32 %off 104 ret ptr addrspace(7) %ret 105} 106 107define ptr addrspace(7) @simple_nusw_gep(ptr addrspace(7) %ptr, i32 %off) { 108; CHECK-LABEL: define { ptr addrspace(8), i32 } @simple_nusw_gep 109; CHECK-SAME: ({ ptr addrspace(8), i32 } [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] { 110; CHECK-NEXT: [[PTR_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 0 111; CHECK-NEXT: [[PTR_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 1 112; CHECK-NEXT: [[RET_IDX:%.*]] = mul nsw i32 [[OFF]], 4 113; CHECK-NEXT: [[RET:%.*]] = add i32 [[PTR_OFF]], [[RET_IDX]] 114; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[PTR_RSRC]], 0 115; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP1]], i32 [[RET]], 1 116; CHECK-NEXT: ret { ptr addrspace(8), i32 } [[TMP2]] 117; 118 %ret = getelementptr nusw i32, ptr addrspace(7) %ptr, i32 %off 119 ret ptr addrspace(7) %ret 120} 121 122define ptr addrspace(7) @nusw_gep_pair(ptr addrspace(7) %ptr, i32 %off) { 123; CHECK-LABEL: define { ptr addrspace(8), i32 } @nusw_gep_pair 124; CHECK-SAME: ({ ptr addrspace(8), i32 } [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] { 125; CHECK-NEXT: [[PTR_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 0 126; CHECK-NEXT: [[PTR_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 1 127; CHECK-NEXT: [[P1_IDX:%.*]] = mul nsw i32 [[OFF]], 4 128; CHECK-NEXT: [[P1:%.*]] = add i32 [[PTR_OFF]], [[P1_IDX]] 129; CHECK-NEXT: [[RET:%.*]] = add nuw i32 [[P1]], 16 130; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[PTR_RSRC]], 0 131; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP1]], i32 [[RET]], 1 132; CHECK-NEXT: ret { ptr addrspace(8), i32 } [[TMP2]] 133; 134 %p1 = getelementptr nusw i32, ptr addrspace(7) %ptr, i32 %off 135 %ret = getelementptr nusw i32, ptr addrspace(7) %p1, i32 4 136 ret ptr addrspace(7) %ret 137} 138 139define ptr addrspace(7) @zero_gep(ptr addrspace(7) %ptr) { 140; CHECK-LABEL: define { ptr addrspace(8), i32 } @zero_gep 141; CHECK-SAME: ({ ptr addrspace(8), i32 } [[PTR:%.*]]) #[[ATTR0]] { 142; CHECK-NEXT: [[PTR_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 0 143; CHECK-NEXT: [[PTR_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 1 144; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[PTR_RSRC]], 0 145; CHECK-NEXT: [[RET:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP1]], i32 [[PTR_OFF]], 1 146; CHECK-NEXT: ret { ptr addrspace(8), i32 } [[RET]] 147; 148 %ret = getelementptr i8, ptr addrspace(7) %ptr, i32 0 149 ret ptr addrspace(7) %ret 150} 151 152define ptr addrspace(7) @zero_gep_goes_second(ptr addrspace(7) %v0, i32 %arg) { 153; CHECK-LABEL: define { ptr addrspace(8), i32 } @zero_gep_goes_second 154; CHECK-SAME: ({ ptr addrspace(8), i32 } [[V0:%.*]], i32 [[ARG:%.*]]) #[[ATTR0]] { 155; CHECK-NEXT: [[V0_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[V0]], 0 156; CHECK-NEXT: [[V0_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[V0]], 1 157; CHECK-NEXT: [[V1:%.*]] = add i32 [[V0_OFF]], [[ARG]] 158; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[V0_RSRC]], 0 159; CHECK-NEXT: [[V2:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP1]], i32 [[V1]], 1 160; CHECK-NEXT: ret { ptr addrspace(8), i32 } [[V2]] 161; 162 %v1 = getelementptr i8, ptr addrspace(7) %v0, i32 %arg 163 %v2 = getelementptr i8, ptr addrspace(7) %v1, i32 0 164 ret ptr addrspace(7) %v2 165} 166 167define ptr addrspace(7) @zero_gep_goes_first(ptr addrspace(7) %v0, i32 %arg) { 168; CHECK-LABEL: define { ptr addrspace(8), i32 } @zero_gep_goes_first 169; CHECK-SAME: ({ ptr addrspace(8), i32 } [[V0:%.*]], i32 [[ARG:%.*]]) #[[ATTR0]] { 170; CHECK-NEXT: [[V0_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[V0]], 0 171; CHECK-NEXT: [[V0_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[V0]], 1 172; CHECK-NEXT: [[V2:%.*]] = add i32 [[V0_OFF]], [[ARG]] 173; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[V0_RSRC]], 0 174; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP1]], i32 [[V2]], 1 175; CHECK-NEXT: ret { ptr addrspace(8), i32 } [[TMP2]] 176; 177 %v1 = getelementptr i8, ptr addrspace(7) %v0, i32 0 178 %v2 = getelementptr i8, ptr addrspace(7) %v1, i32 %arg 179 ret ptr addrspace(7) %v2 180} 181 182define i160 @ptrtoint(ptr addrspace(7) %ptr) { 183; CHECK-LABEL: define i160 @ptrtoint 184; CHECK-SAME: ({ ptr addrspace(8), i32 } [[PTR:%.*]]) #[[ATTR0]] { 185; CHECK-NEXT: [[PTR_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 0 186; CHECK-NEXT: [[PTR_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 1 187; CHECK-NEXT: [[RET_RSRC:%.*]] = ptrtoint ptr addrspace(8) [[PTR_RSRC]] to i160 188; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i160 [[RET_RSRC]], 32 189; CHECK-NEXT: [[RET_OFF:%.*]] = zext i32 [[PTR_OFF]] to i160 190; CHECK-NEXT: [[RET:%.*]] = or i160 [[TMP1]], [[RET_OFF]] 191; CHECK-NEXT: ret i160 [[RET]] 192; 193 %ret = ptrtoint ptr addrspace(7) %ptr to i160 194 ret i160 %ret 195} 196 197define <2 x i160> @ptrtoint_vec(<2 x ptr addrspace(7)> %ptr) { 198; CHECK-LABEL: define <2 x i160> @ptrtoint_vec 199; CHECK-SAME: ({ <2 x ptr addrspace(8)>, <2 x i32> } [[PTR:%.*]]) #[[ATTR0]] { 200; CHECK-NEXT: [[PTR_RSRC:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[PTR]], 0 201; CHECK-NEXT: [[PTR_OFF:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[PTR]], 1 202; CHECK-NEXT: [[RET_RSRC:%.*]] = ptrtoint <2 x ptr addrspace(8)> [[PTR_RSRC]] to <2 x i160> 203; CHECK-NEXT: [[TMP1:%.*]] = shl nuw <2 x i160> [[RET_RSRC]], splat (i160 32) 204; CHECK-NEXT: [[RET_OFF:%.*]] = zext <2 x i32> [[PTR_OFF]] to <2 x i160> 205; CHECK-NEXT: [[RET:%.*]] = or <2 x i160> [[TMP1]], [[RET_OFF]] 206; CHECK-NEXT: ret <2 x i160> [[RET]] 207; 208 %ret = ptrtoint <2 x ptr addrspace(7)> %ptr to <2 x i160> 209 ret <2 x i160> %ret 210} 211 212define i256 @ptrtoint_long(ptr addrspace(7) %ptr) { 213; CHECK-LABEL: define i256 @ptrtoint_long 214; CHECK-SAME: ({ ptr addrspace(8), i32 } [[PTR:%.*]]) #[[ATTR0]] { 215; CHECK-NEXT: [[PTR_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 0 216; CHECK-NEXT: [[PTR_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 1 217; CHECK-NEXT: [[RET_RSRC:%.*]] = ptrtoint ptr addrspace(8) [[PTR_RSRC]] to i256 218; CHECK-NEXT: [[TMP1:%.*]] = shl nuw nsw i256 [[RET_RSRC]], 32 219; CHECK-NEXT: [[RET_OFF:%.*]] = zext i32 [[PTR_OFF]] to i256 220; CHECK-NEXT: [[RET:%.*]] = or i256 [[TMP1]], [[RET_OFF]] 221; CHECK-NEXT: ret i256 [[RET]] 222; 223 %ret = ptrtoint ptr addrspace(7) %ptr to i256 224 ret i256 %ret 225} 226 227define i64 @ptrtoint_short(ptr addrspace(7) %ptr) { 228; CHECK-LABEL: define i64 @ptrtoint_short 229; CHECK-SAME: ({ ptr addrspace(8), i32 } [[PTR:%.*]]) #[[ATTR0]] { 230; CHECK-NEXT: [[PTR_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 0 231; CHECK-NEXT: [[PTR_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 1 232; CHECK-NEXT: [[RET_RSRC:%.*]] = ptrtoint ptr addrspace(8) [[PTR_RSRC]] to i64 233; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[RET_RSRC]], 32 234; CHECK-NEXT: [[RET_OFF:%.*]] = zext i32 [[PTR_OFF]] to i64 235; CHECK-NEXT: [[RET:%.*]] = or i64 [[TMP1]], [[RET_OFF]] 236; CHECK-NEXT: ret i64 [[RET]] 237; 238 %ret = ptrtoint ptr addrspace(7) %ptr to i64 239 ret i64 %ret 240} 241 242define i32 @ptrtoint_offset(ptr addrspace(7) %ptr) { 243; CHECK-LABEL: define i32 @ptrtoint_offset 244; CHECK-SAME: ({ ptr addrspace(8), i32 } [[PTR:%.*]]) #[[ATTR0]] { 245; CHECK-NEXT: [[PTR_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 0 246; CHECK-NEXT: [[RET:%.*]] = extractvalue { ptr addrspace(8), i32 } [[PTR]], 1 247; CHECK-NEXT: ret i32 [[RET]] 248; 249 %ret = ptrtoint ptr addrspace(7) %ptr to i32 250 ret i32 %ret 251} 252 253define ptr addrspace(7) @inttoptr(i160 %v) { 254; CHECK-LABEL: define { ptr addrspace(8), i32 } @inttoptr 255; CHECK-SAME: (i160 [[V:%.*]]) #[[ATTR0]] { 256; CHECK-NEXT: [[TMP1:%.*]] = lshr i160 [[V]], 32 257; CHECK-NEXT: [[TMP2:%.*]] = trunc i160 [[TMP1]] to i128 258; CHECK-NEXT: [[RET_RSRC:%.*]] = inttoptr i128 [[TMP2]] to ptr addrspace(8) 259; CHECK-NEXT: [[RET_OFF:%.*]] = trunc i160 [[V]] to i32 260; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[RET_RSRC]], 0 261; CHECK-NEXT: [[RET:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP3]], i32 [[RET_OFF]], 1 262; CHECK-NEXT: ret { ptr addrspace(8), i32 } [[RET]] 263; 264 %ret = inttoptr i160 %v to ptr addrspace(7) 265 ret ptr addrspace(7) %ret 266} 267 268define <2 x ptr addrspace(7)> @inttoptr_vec(<2 x i160> %v) { 269; CHECK-LABEL: define { <2 x ptr addrspace(8)>, <2 x i32> } @inttoptr_vec 270; CHECK-SAME: (<2 x i160> [[V:%.*]]) #[[ATTR0]] { 271; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i160> [[V]], splat (i160 32) 272; CHECK-NEXT: [[TMP2:%.*]] = trunc <2 x i160> [[TMP1]] to <2 x i128> 273; CHECK-NEXT: [[RET_RSRC:%.*]] = inttoptr <2 x i128> [[TMP2]] to <2 x ptr addrspace(8)> 274; CHECK-NEXT: [[RET_OFF:%.*]] = trunc <2 x i160> [[V]] to <2 x i32> 275; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { <2 x ptr addrspace(8)>, <2 x i32> } poison, <2 x ptr addrspace(8)> [[RET_RSRC]], 0 276; CHECK-NEXT: [[RET:%.*]] = insertvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[TMP3]], <2 x i32> [[RET_OFF]], 1 277; CHECK-NEXT: ret { <2 x ptr addrspace(8)>, <2 x i32> } [[RET]] 278; 279 %ret = inttoptr <2 x i160> %v to <2 x ptr addrspace(7)> 280 ret <2 x ptr addrspace(7)> %ret 281} 282 283define ptr addrspace(7) @inttoptr_long(i256 %v) { 284; CHECK-LABEL: define { ptr addrspace(8), i32 } @inttoptr_long 285; CHECK-SAME: (i256 [[V:%.*]]) #[[ATTR0]] { 286; CHECK-NEXT: [[TMP1:%.*]] = lshr i256 [[V]], 32 287; CHECK-NEXT: [[TMP2:%.*]] = trunc i256 [[TMP1]] to i128 288; CHECK-NEXT: [[RET_RSRC:%.*]] = inttoptr i128 [[TMP2]] to ptr addrspace(8) 289; CHECK-NEXT: [[RET_OFF:%.*]] = trunc i256 [[V]] to i32 290; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[RET_RSRC]], 0 291; CHECK-NEXT: [[RET:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP3]], i32 [[RET_OFF]], 1 292; CHECK-NEXT: ret { ptr addrspace(8), i32 } [[RET]] 293; 294 %ret = inttoptr i256 %v to ptr addrspace(7) 295 ret ptr addrspace(7) %ret 296} 297 298define ptr addrspace(7) @inttoptr_offset(i32 %v) { 299; CHECK-LABEL: define { ptr addrspace(8), i32 } @inttoptr_offset 300; CHECK-SAME: (i32 [[V:%.*]]) #[[ATTR0]] { 301; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[V]], 32 302; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i128 303; CHECK-NEXT: [[RET_RSRC:%.*]] = inttoptr i128 [[TMP2]] to ptr addrspace(8) 304; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[RET_RSRC]], 0 305; CHECK-NEXT: [[RET:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP3]], i32 [[V]], 1 306; CHECK-NEXT: ret { ptr addrspace(8), i32 } [[RET]] 307; 308 %ret = inttoptr i32 %v to ptr addrspace(7) 309 ret ptr addrspace(7) %ret 310} 311 312define ptr addrspace(7) @addrspacecast(ptr addrspace(8) %buf) { 313; CHECK-LABEL: define { ptr addrspace(8), i32 } @addrspacecast 314; CHECK-SAME: (ptr addrspace(8) [[BUF:%.*]]) #[[ATTR0]] { 315; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[BUF]], 0 316; CHECK-NEXT: [[RET:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP1]], i32 0, 1 317; CHECK-NEXT: ret { ptr addrspace(8), i32 } [[RET]] 318; 319 %ret = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7) 320 ret ptr addrspace(7) %ret 321} 322 323define <2 x ptr addrspace(7)> @addrspacecast_vec(<2 x ptr addrspace(8)> %buf) { 324; CHECK-LABEL: define { <2 x ptr addrspace(8)>, <2 x i32> } @addrspacecast_vec 325; CHECK-SAME: (<2 x ptr addrspace(8)> [[BUF:%.*]]) #[[ATTR0]] { 326; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { <2 x ptr addrspace(8)>, <2 x i32> } poison, <2 x ptr addrspace(8)> [[BUF]], 0 327; CHECK-NEXT: [[RET:%.*]] = insertvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[TMP1]], <2 x i32> zeroinitializer, 1 328; CHECK-NEXT: ret { <2 x ptr addrspace(8)>, <2 x i32> } [[RET]] 329; 330 %ret = addrspacecast <2 x ptr addrspace(8)> %buf to <2 x ptr addrspace(7)> 331 ret <2 x ptr addrspace(7)> %ret 332} 333 334define i1 @icmp_eq(ptr addrspace(7) %a, ptr addrspace(7) %b) { 335; CHECK-LABEL: define i1 @icmp_eq 336; CHECK-SAME: ({ ptr addrspace(8), i32 } [[A:%.*]], { ptr addrspace(8), i32 } [[B:%.*]]) #[[ATTR0]] { 337; CHECK-NEXT: [[B_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[B]], 0 338; CHECK-NEXT: [[B_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[B]], 1 339; CHECK-NEXT: [[A_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[A]], 0 340; CHECK-NEXT: [[A_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[A]], 1 341; CHECK-NEXT: [[RET_RSRC:%.*]] = icmp eq ptr addrspace(8) [[A_RSRC]], [[B_RSRC]] 342; CHECK-NEXT: [[RET_OFF:%.*]] = icmp eq i32 [[A_OFF]], [[B_OFF]] 343; CHECK-NEXT: [[RET:%.*]] = and i1 [[RET_RSRC]], [[RET_OFF]] 344; CHECK-NEXT: ret i1 [[RET]] 345; 346 %ret = icmp eq ptr addrspace(7) %a, %b 347 ret i1 %ret 348} 349 350define i1 @icmp_ne(ptr addrspace(7) %a, ptr addrspace(7) %b) { 351; CHECK-LABEL: define i1 @icmp_ne 352; CHECK-SAME: ({ ptr addrspace(8), i32 } [[A:%.*]], { ptr addrspace(8), i32 } [[B:%.*]]) #[[ATTR0]] { 353; CHECK-NEXT: [[B_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[B]], 0 354; CHECK-NEXT: [[B_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[B]], 1 355; CHECK-NEXT: [[A_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[A]], 0 356; CHECK-NEXT: [[A_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[A]], 1 357; CHECK-NEXT: [[RET_RSRC:%.*]] = icmp ne ptr addrspace(8) [[A_RSRC]], [[B_RSRC]] 358; CHECK-NEXT: [[RET_OFF:%.*]] = icmp ne i32 [[A_OFF]], [[B_OFF]] 359; CHECK-NEXT: [[RET:%.*]] = or i1 [[RET_RSRC]], [[RET_OFF]] 360; CHECK-NEXT: ret i1 [[RET]] 361; 362 %ret = icmp ne ptr addrspace(7) %a, %b 363 ret i1 %ret 364} 365 366define <2 x i1> @icmp_eq_vec(<2 x ptr addrspace(7)> %a, <2 x ptr addrspace(7)> %b) { 367; CHECK-LABEL: define <2 x i1> @icmp_eq_vec 368; CHECK-SAME: ({ <2 x ptr addrspace(8)>, <2 x i32> } [[A:%.*]], { <2 x ptr addrspace(8)>, <2 x i32> } [[B:%.*]]) #[[ATTR0]] { 369; CHECK-NEXT: [[B_RSRC:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[B]], 0 370; CHECK-NEXT: [[B_OFF:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[B]], 1 371; CHECK-NEXT: [[A_RSRC:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[A]], 0 372; CHECK-NEXT: [[A_OFF:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[A]], 1 373; CHECK-NEXT: [[RET_RSRC:%.*]] = icmp eq <2 x ptr addrspace(8)> [[A_RSRC]], [[B_RSRC]] 374; CHECK-NEXT: [[RET_OFF:%.*]] = icmp eq <2 x i32> [[A_OFF]], [[B_OFF]] 375; CHECK-NEXT: [[RET:%.*]] = and <2 x i1> [[RET_RSRC]], [[RET_OFF]] 376; CHECK-NEXT: ret <2 x i1> [[RET]] 377; 378 %ret = icmp eq <2 x ptr addrspace(7)> %a, %b 379 ret <2 x i1> %ret 380} 381 382define <2 x i1> @icmp_ne_vec(<2 x ptr addrspace(7)> %a, <2 x ptr addrspace(7)> %b) { 383; CHECK-LABEL: define <2 x i1> @icmp_ne_vec 384; CHECK-SAME: ({ <2 x ptr addrspace(8)>, <2 x i32> } [[A:%.*]], { <2 x ptr addrspace(8)>, <2 x i32> } [[B:%.*]]) #[[ATTR0]] { 385; CHECK-NEXT: [[B_RSRC:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[B]], 0 386; CHECK-NEXT: [[B_OFF:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[B]], 1 387; CHECK-NEXT: [[A_RSRC:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[A]], 0 388; CHECK-NEXT: [[A_OFF:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[A]], 1 389; CHECK-NEXT: [[RET_RSRC:%.*]] = icmp ne <2 x ptr addrspace(8)> [[A_RSRC]], [[B_RSRC]] 390; CHECK-NEXT: [[RET_OFF:%.*]] = icmp ne <2 x i32> [[A_OFF]], [[B_OFF]] 391; CHECK-NEXT: [[RET:%.*]] = or <2 x i1> [[RET_RSRC]], [[RET_OFF]] 392; CHECK-NEXT: ret <2 x i1> [[RET]] 393; 394 %ret = icmp ne <2 x ptr addrspace(7)> %a, %b 395 ret <2 x i1> %ret 396} 397 398define ptr addrspace(7) @freeze(ptr addrspace(7) %p) { 399; CHECK-LABEL: define { ptr addrspace(8), i32 } @freeze 400; CHECK-SAME: ({ ptr addrspace(8), i32 } [[P:%.*]]) #[[ATTR0]] { 401; CHECK-NEXT: [[P_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[P]], 0 402; CHECK-NEXT: [[P_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[P]], 1 403; CHECK-NEXT: [[RET_RSRC:%.*]] = freeze ptr addrspace(8) [[P_RSRC]] 404; CHECK-NEXT: [[RET_OFF:%.*]] = freeze i32 [[P_OFF]] 405; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[RET_RSRC]], 0 406; CHECK-NEXT: [[RET:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP1]], i32 [[RET_OFF]], 1 407; CHECK-NEXT: ret { ptr addrspace(8), i32 } [[RET]] 408; 409 %ret = freeze ptr addrspace(7) %p 410 ret ptr addrspace(7) %ret 411} 412 413define <2 x ptr addrspace(7)> @freeze_vec(<2 x ptr addrspace(7)> %p) { 414; CHECK-LABEL: define { <2 x ptr addrspace(8)>, <2 x i32> } @freeze_vec 415; CHECK-SAME: ({ <2 x ptr addrspace(8)>, <2 x i32> } [[P:%.*]]) #[[ATTR0]] { 416; CHECK-NEXT: [[P_RSRC:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[P]], 0 417; CHECK-NEXT: [[P_OFF:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[P]], 1 418; CHECK-NEXT: [[RET_RSRC:%.*]] = freeze <2 x ptr addrspace(8)> [[P_RSRC]] 419; CHECK-NEXT: [[RET_OFF:%.*]] = freeze <2 x i32> [[P_OFF]] 420; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { <2 x ptr addrspace(8)>, <2 x i32> } poison, <2 x ptr addrspace(8)> [[RET_RSRC]], 0 421; CHECK-NEXT: [[RET:%.*]] = insertvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[TMP1]], <2 x i32> [[RET_OFF]], 1 422; CHECK-NEXT: ret { <2 x ptr addrspace(8)>, <2 x i32> } [[RET]] 423; 424 %ret = freeze <2 x ptr addrspace(7)> %p 425 ret <2 x ptr addrspace(7)> %ret 426} 427 428define ptr addrspace(7) @extractelement(<2 x ptr addrspace(7)> %v, i32 %i) { 429; CHECK-LABEL: define { ptr addrspace(8), i32 } @extractelement 430; CHECK-SAME: ({ <2 x ptr addrspace(8)>, <2 x i32> } [[V:%.*]], i32 [[I:%.*]]) #[[ATTR0]] { 431; CHECK-NEXT: [[V_RSRC:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[V]], 0 432; CHECK-NEXT: [[V_OFF:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[V]], 1 433; CHECK-NEXT: [[RET_RSRC:%.*]] = extractelement <2 x ptr addrspace(8)> [[V_RSRC]], i32 [[I]] 434; CHECK-NEXT: [[RET_OFF:%.*]] = extractelement <2 x i32> [[V_OFF]], i32 [[I]] 435; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[RET_RSRC]], 0 436; CHECK-NEXT: [[RET:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP1]], i32 [[RET_OFF]], 1 437; CHECK-NEXT: ret { ptr addrspace(8), i32 } [[RET]] 438; 439 %ret = extractelement <2 x ptr addrspace(7)> %v, i32 %i 440 ret ptr addrspace(7) %ret 441} 442 443define <2 x ptr addrspace(7)> @insertelement(<2 x ptr addrspace(7)> %v, ptr addrspace(7) %s, i32 %i) { 444; CHECK-LABEL: define { <2 x ptr addrspace(8)>, <2 x i32> } @insertelement 445; CHECK-SAME: ({ <2 x ptr addrspace(8)>, <2 x i32> } [[V:%.*]], { ptr addrspace(8), i32 } [[S:%.*]], i32 [[I:%.*]]) #[[ATTR0]] { 446; CHECK-NEXT: [[S_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[S]], 0 447; CHECK-NEXT: [[S_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[S]], 1 448; CHECK-NEXT: [[V_RSRC:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[V]], 0 449; CHECK-NEXT: [[V_OFF:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[V]], 1 450; CHECK-NEXT: [[RET_RSRC:%.*]] = insertelement <2 x ptr addrspace(8)> [[V_RSRC]], ptr addrspace(8) [[S_RSRC]], i32 [[I]] 451; CHECK-NEXT: [[RET_OFF:%.*]] = insertelement <2 x i32> [[V_OFF]], i32 [[S_OFF]], i32 [[I]] 452; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { <2 x ptr addrspace(8)>, <2 x i32> } poison, <2 x ptr addrspace(8)> [[RET_RSRC]], 0 453; CHECK-NEXT: [[RET:%.*]] = insertvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[TMP1]], <2 x i32> [[RET_OFF]], 1 454; CHECK-NEXT: ret { <2 x ptr addrspace(8)>, <2 x i32> } [[RET]] 455; 456 %ret = insertelement <2 x ptr addrspace(7)> %v, ptr addrspace(7) %s, i32 %i 457 ret <2 x ptr addrspace(7)> %ret 458} 459 460define <4 x ptr addrspace(7)> @shufflenvector(<2 x ptr addrspace(7)> %a, <2 x ptr addrspace(7)> %b) { 461; CHECK-LABEL: define { <4 x ptr addrspace(8)>, <4 x i32> } @shufflenvector 462; CHECK-SAME: ({ <2 x ptr addrspace(8)>, <2 x i32> } [[A:%.*]], { <2 x ptr addrspace(8)>, <2 x i32> } [[B:%.*]]) #[[ATTR0]] { 463; CHECK-NEXT: [[B_RSRC:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[B]], 0 464; CHECK-NEXT: [[B_OFF:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[B]], 1 465; CHECK-NEXT: [[A_RSRC:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[A]], 0 466; CHECK-NEXT: [[A_OFF:%.*]] = extractvalue { <2 x ptr addrspace(8)>, <2 x i32> } [[A]], 1 467; CHECK-NEXT: [[RET_RSRC:%.*]] = shufflevector <2 x ptr addrspace(8)> [[A_RSRC]], <2 x ptr addrspace(8)> [[B_RSRC]], <4 x i32> <i32 0, i32 3, i32 1, i32 2> 468; CHECK-NEXT: [[RET_OFF:%.*]] = shufflevector <2 x i32> [[A_OFF]], <2 x i32> [[B_OFF]], <4 x i32> <i32 0, i32 3, i32 1, i32 2> 469; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { <4 x ptr addrspace(8)>, <4 x i32> } poison, <4 x ptr addrspace(8)> [[RET_RSRC]], 0 470; CHECK-NEXT: [[RET:%.*]] = insertvalue { <4 x ptr addrspace(8)>, <4 x i32> } [[TMP1]], <4 x i32> [[RET_OFF]], 1 471; CHECK-NEXT: ret { <4 x ptr addrspace(8)>, <4 x i32> } [[RET]] 472; 473 %ret = shufflevector <2 x ptr addrspace(7)> %a, <2 x ptr addrspace(7)> %b, <4 x i32> <i32 0, i32 3, i32 1, i32 2> 474 ret <4 x ptr addrspace(7)> %ret 475} 476 477declare ptr addrspace(7) @llvm.ptrmask.p7.i32(ptr addrspace(7), i32) 478 479define ptr addrspace(7) @ptrmask(ptr addrspace(7) %p, i32 %mask) { 480; CHECK-LABEL: define { ptr addrspace(8), i32 } @ptrmask 481; CHECK-SAME: ({ ptr addrspace(8), i32 } [[P:%.*]], i32 [[MASK:%.*]]) #[[ATTR0]] { 482; CHECK-NEXT: [[P_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[P]], 0 483; CHECK-NEXT: [[P_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[P]], 1 484; CHECK-NEXT: [[RET_OFF:%.*]] = and i32 [[P_OFF]], [[MASK]] 485; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[P_RSRC]], 0 486; CHECK-NEXT: [[RET:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP1]], i32 [[RET_OFF]], 1 487; CHECK-NEXT: ret { ptr addrspace(8), i32 } [[RET]] 488; 489 %ret = call ptr addrspace(7) @llvm.ptrmask.p7.i32(ptr addrspace(7) %p, i32 %mask) 490 ret ptr addrspace(7) %ret 491} 492 493declare ptr @llvm.invariant.start.p7(i64, ptr addrspace(7) nocapture) 494declare void @llvm.invariant.end.p7(ptr, i64, ptr addrspace(7) nocapture) 495 496define i32 @invariant_start_end(ptr addrspace(7) %p) { 497; CHECK-LABEL: define i32 @invariant_start_end 498; CHECK-SAME: ({ ptr addrspace(8), i32 } [[P:%.*]]) #[[ATTR0]] { 499; CHECK-NEXT: [[P_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[P]], 0 500; CHECK-NEXT: [[P_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[P]], 1 501; CHECK-NEXT: [[INV:%.*]] = call ptr @llvm.invariant.start.p8(i64 256, ptr addrspace(8) [[P_RSRC]]) 502; CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.raw.ptr.buffer.load.i32(ptr addrspace(8) align 4 [[P_RSRC]], i32 [[P_OFF]], i32 0, i32 0) 503; CHECK-NEXT: call void @llvm.invariant.end.p8(ptr [[INV]], i64 256, ptr addrspace(8) [[P_RSRC]]) 504; CHECK-NEXT: ret i32 [[V]] 505; 506 %inv = call ptr @llvm.invariant.start.p7(i64 256, ptr addrspace(7) %p) 507 %v = load i32, ptr addrspace(7) %p 508 call void @llvm.invariant.end.p7(ptr %inv, i64 256, ptr addrspace(7) %p) 509 ret i32 %v 510} 511 512declare ptr addrspace(7) @llvm.launder.invariant.group.p7(ptr addrspace(7) nocapture) 513declare ptr addrspace(7) @llvm.strip.invariant.group.p7(ptr addrspace(7) nocapture) 514 515define ptr addrspace(7) @invariant_group(ptr addrspace(7) %p) { 516; CHECK-LABEL: define { ptr addrspace(8), i32 } @invariant_group 517; CHECK-SAME: ({ ptr addrspace(8), i32 } [[P:%.*]]) #[[ATTR0]] { 518; CHECK-NEXT: [[P_RSRC:%.*]] = extractvalue { ptr addrspace(8), i32 } [[P]], 0 519; CHECK-NEXT: [[P_OFF:%.*]] = extractvalue { ptr addrspace(8), i32 } [[P]], 1 520; CHECK-NEXT: [[LAUNDERED:%.*]] = call ptr addrspace(8) @llvm.launder.invariant.group.p8(ptr addrspace(8) [[P_RSRC]]) 521; CHECK-NEXT: [[STRIPPED:%.*]] = call ptr addrspace(8) @llvm.strip.invariant.group.p8(ptr addrspace(8) [[LAUNDERED]]) 522; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { ptr addrspace(8), i32 } poison, ptr addrspace(8) [[STRIPPED]], 0 523; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { ptr addrspace(8), i32 } [[TMP1]], i32 [[P_OFF]], 1 524; CHECK-NEXT: ret { ptr addrspace(8), i32 } [[TMP2]] 525; 526 %laundered = call ptr addrspace(7) @llvm.launder.invariant.group.p7(ptr addrspace(7) %p) 527 %stripped = call ptr addrspace(7) @llvm.strip.invariant.group.p7(ptr addrspace(7) %laundered) 528 ret ptr addrspace(7) %stripped 529} 530