Skip to content

Commit 065d3ba

Browse files
committed
[NVPTX] instcombine known pointer AS checks.
This avoids crashing on impossible address space casts guarded by `__isGlobal/__isShared`.
1 parent 6c64c8a commit 065d3ba

File tree

4 files changed

+326
-10
lines changed

4 files changed

+326
-10
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===---------------- AMDGPUAddrSpace.h -------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
/// \file
10+
/// AMDGPU address space definition
11+
///
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#ifndef LLVM_SUPPORT_NVPTXADDRSPACE_H
16+
#define LLVM_SUPPORT_NVPTXADDRSPACE_H
17+
18+
namespace llvm {
19+
namespace NVPTXAS {
20+
enum AddressSpace : unsigned {
21+
ADDRESS_SPACE_GENERIC = 0,
22+
ADDRESS_SPACE_GLOBAL = 1,
23+
ADDRESS_SPACE_SHARED = 3,
24+
ADDRESS_SPACE_CONST = 4,
25+
ADDRESS_SPACE_LOCAL = 5,
26+
27+
ADDRESS_SPACE_PARAM = 101,
28+
};
29+
} // end namespace NVPTXAS
30+
31+
} // end namespace llvm
32+
33+
#endif // LLVM_SUPPORT_NVPTXADDRSPACE_H

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@
3838
#include "llvm/IR/Dominators.h"
3939
#include "llvm/IR/InstrTypes.h"
4040
#include "llvm/IR/Instructions.h"
41+
#include "llvm/IR/IntrinsicsNVPTX.h"
4142
#include "llvm/IR/Operator.h"
4243
#include "llvm/IR/PatternMatch.h"
4344
#include "llvm/IR/Statepoint.h"
4445
#include "llvm/Support/KnownBits.h"
46+
#include "llvm/Support/NVPTXAddrSpace.h"
4547
#include <algorithm>
4648
#include <optional>
4749
using namespace llvm;
@@ -6365,6 +6367,34 @@ static Value *simplifyUnaryIntrinsic(Function *F, Value *Op0,
63656367

63666368
break;
63676369
}
6370+
case Intrinsic::nvvm_isspacep_global:
6371+
case Intrinsic::nvvm_isspacep_local:
6372+
case Intrinsic::nvvm_isspacep_shared:
6373+
case Intrinsic::nvvm_isspacep_const: {
6374+
auto *Ty = F->getReturnType();
6375+
unsigned AS = Op0->getType()->getPointerAddressSpace();
6376+
if (AS == NVPTXAS::ADDRESS_SPACE_GENERIC) {
6377+
if (auto *ASC = dyn_cast<AddrSpaceCastInst>(Op0))
6378+
AS = ASC->getSrcAddressSpace();
6379+
else if (auto *CE = dyn_cast<ConstantExpr>(Op0)) {
6380+
if (CE->getOpcode() == Instruction::AddrSpaceCast)
6381+
AS = CE->getOperand(0)->getType()->getPointerAddressSpace();
6382+
}
6383+
}
6384+
if (AS == NVPTXAS::ADDRESS_SPACE_GENERIC ||
6385+
AS == NVPTXAS::ADDRESS_SPACE_PARAM)
6386+
return nullptr; // Got to check at run-time.
6387+
bool ASMatches = (AS == NVPTXAS::ADDRESS_SPACE_GLOBAL &&
6388+
IID == Intrinsic::nvvm_isspacep_global) ||
6389+
(AS == NVPTXAS::ADDRESS_SPACE_LOCAL &&
6390+
IID == Intrinsic::nvvm_isspacep_local) ||
6391+
(AS == NVPTXAS::ADDRESS_SPACE_SHARED &&
6392+
IID == Intrinsic::nvvm_isspacep_shared) ||
6393+
(AS == NVPTXAS::ADDRESS_SPACE_CONST &&
6394+
IID == Intrinsic::nvvm_isspacep_const);
6395+
return ConstantInt::get(Ty, ASMatches);
6396+
break;
6397+
}
63686398
default:
63696399
break;
63706400
}

llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXBaseInfo.h

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,10 @@
1616
#ifndef LLVM_LIB_TARGET_NVPTX_MCTARGETDESC_NVPTXBASEINFO_H
1717
#define LLVM_LIB_TARGET_NVPTX_MCTARGETDESC_NVPTXBASEINFO_H
1818

19+
#include "llvm/Support/NVPTXAddrSpace.h"
1920
namespace llvm {
2021

21-
enum AddressSpace {
22-
ADDRESS_SPACE_GENERIC = 0,
23-
ADDRESS_SPACE_GLOBAL = 1,
24-
ADDRESS_SPACE_SHARED = 3,
25-
ADDRESS_SPACE_CONST = 4,
26-
ADDRESS_SPACE_LOCAL = 5,
27-
28-
// NVVM Internal
29-
ADDRESS_SPACE_PARAM = 101
30-
};
22+
using namespace NVPTXAS;
3123

3224
namespace NVPTXII {
3325
enum {
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt < %s -passes=instcombine -mtriple=nvptx64-nvidia-cuda -S | FileCheck %s
3+
target datalayout = "e-i64:64-i128:128-v16:16-v32:32-n16:32:64"
4+
target triple = "nvptx64-nvidia-cuda"
5+
6+
; Source data in different AS.
7+
@shared_data = dso_local addrspace(3) global i32 undef, align 4
8+
@global_data = dso_local addrspace(1) externally_initialized global i32 0, align 4
9+
@const_data = dso_local addrspace(4) externally_initialized constant i32 3, align 4
10+
11+
; Results get stored here.
12+
@gen = dso_local addrspace(1) externally_initialized global i8 0, align 1
13+
@g1 = dso_local addrspace(1) externally_initialized global i8 0, align 1
14+
@g2 = dso_local addrspace(1) externally_initialized global i8 0, align 1
15+
@s1 = dso_local addrspace(1) externally_initialized global i8 0, align 1
16+
@s2 = dso_local addrspace(1) externally_initialized global i8 0, align 1
17+
@c1 = dso_local addrspace(1) externally_initialized global i8 0, align 1
18+
@c2 = dso_local addrspace(1) externally_initialized global i8 0, align 1
19+
@l = dso_local addrspace(1) externally_initialized global i8 0, align 1
20+
21+
declare i1 @llvm.nvvm.isspacep.global(ptr nocapture)
22+
declare i1 @llvm.nvvm.isspacep.shared(ptr nocapture)
23+
declare i1 @llvm.nvvm.isspacep.const(ptr nocapture)
24+
declare i1 @llvm.nvvm.isspacep.local(ptr nocapture)
25+
26+
define dso_local void @check_global(ptr nocapture noundef readnone %out, ptr nocapture noundef readnone %generic_data, ptr addrspace(5) %local_data) local_unnamed_addr {
27+
; CHECK-LABEL: define dso_local void @check_global(
28+
; CHECK-SAME: ptr nocapture noundef readnone [[OUT:%.*]], ptr nocapture noundef readnone [[GENERIC_DATA:%.*]], ptr addrspace(5) [[LOCAL_DATA:%.*]]) local_unnamed_addr {
29+
; CHECK-NEXT: [[ENTRY:.*:]]
30+
; CHECK-NEXT: [[GEN0:%.*]] = tail call i1 @llvm.nvvm.isspacep.global(ptr [[GENERIC_DATA]])
31+
; CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[GEN0]] to i8
32+
; CHECK-NEXT: store i8 [[STOREDV]], ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1
33+
; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1
34+
; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1
35+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1
36+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1
37+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1
38+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1
39+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1
40+
; CHECK-NEXT: ret void
41+
;
42+
entry:
43+
; No constant folding for generic pointers of unknown origin.
44+
%gen0 = tail call i1 @llvm.nvvm.isspacep.global(ptr %generic_data)
45+
%storedv = zext i1 %gen0 to i8
46+
store i8 %storedv, ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1
47+
48+
%isg1 = tail call i1 @llvm.nvvm.isspacep.global(ptr addrspacecast (ptr addrspace(1) @global_data to ptr))
49+
%isg18 = zext i1 %isg1 to i8
50+
store i8 %isg18, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1
51+
52+
%global_data_asc = addrspacecast ptr addrspace(1) @global_data to ptr
53+
%isg2 = tail call i1 @llvm.nvvm.isspacep.global(ptr %global_data_asc)
54+
%isg28 = zext i1 %isg2 to i8
55+
store i8 %isg28, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1
56+
57+
%iss1 = tail call i1 @llvm.nvvm.isspacep.global(ptr addrspacecast (ptr addrspace(3) @shared_data to ptr))
58+
%iss18 = zext i1 %iss1 to i8
59+
store i8 %iss18, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1
60+
61+
%shared_data_asc = addrspacecast ptr addrspace(3) @shared_data to ptr
62+
%iss2 = tail call i1 @llvm.nvvm.isspacep.global(ptr %shared_data_asc)
63+
%iss28 = zext i1 %iss2 to i8
64+
store i8 %iss28, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1
65+
66+
%isc1 = tail call i1 @llvm.nvvm.isspacep.global(ptr addrspacecast (ptr addrspace(4) @const_data to ptr))
67+
%isc18 = zext i1 %isc1 to i8
68+
store i8 %isc18, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1
69+
70+
%const_data_asc = addrspacecast ptr addrspace(4) @const_data to ptr
71+
%isc2 = tail call i1 @llvm.nvvm.isspacep.global(ptr %const_data_asc)
72+
%isc28 = zext i1 %isc2 to i8
73+
store i8 %isc28, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1
74+
75+
; Local data can't ihave a constant address, so we can't have a constant ASC expression
76+
; We can only use an ASC instruction.
77+
%local_data_asc = addrspacecast ptr addrspace(5) %local_data to ptr
78+
%isl = call i1 @llvm.nvvm.isspacep.global(ptr nonnull %local_data_asc)
79+
%isl8 = zext i1 %isl to i8
80+
store i8 %isl8, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1
81+
82+
ret void
83+
}
84+
85+
define dso_local void @check_shared(ptr nocapture noundef readnone %out, ptr nocapture noundef readnone %generic_data, ptr addrspace(5) %local_data) local_unnamed_addr {
86+
; CHECK-LABEL: define dso_local void @check_shared(
87+
; CHECK-SAME: ptr nocapture noundef readnone [[OUT:%.*]], ptr nocapture noundef readnone [[GENERIC_DATA:%.*]], ptr addrspace(5) [[LOCAL_DATA:%.*]]) local_unnamed_addr {
88+
; CHECK-NEXT: [[ENTRY:.*:]]
89+
; CHECK-NEXT: [[GEN0:%.*]] = tail call i1 @llvm.nvvm.isspacep.shared(ptr [[GENERIC_DATA]])
90+
; CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[GEN0]] to i8
91+
; CHECK-NEXT: store i8 [[STOREDV]], ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1
92+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1
93+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1
94+
; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1
95+
; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1
96+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1
97+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1
98+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1
99+
; CHECK-NEXT: ret void
100+
;
101+
entry:
102+
; No constant folding for generic pointers of unknown origin.
103+
%gen0 = tail call i1 @llvm.nvvm.isspacep.shared(ptr %generic_data)
104+
%storedv = zext i1 %gen0 to i8
105+
store i8 %storedv, ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1
106+
107+
%isg1 = tail call i1 @llvm.nvvm.isspacep.shared(ptr addrspacecast (ptr addrspace(1) @global_data to ptr))
108+
%isg18 = zext i1 %isg1 to i8
109+
store i8 %isg18, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1
110+
111+
%global_data_asc = addrspacecast ptr addrspace(1) @global_data to ptr
112+
%isg2 = tail call i1 @llvm.nvvm.isspacep.shared(ptr %global_data_asc)
113+
%isg28 = zext i1 %isg2 to i8
114+
store i8 %isg28, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1
115+
116+
%iss1 = tail call i1 @llvm.nvvm.isspacep.shared(ptr addrspacecast (ptr addrspace(3) @shared_data to ptr))
117+
%iss18 = zext i1 %iss1 to i8
118+
store i8 %iss18, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1
119+
120+
%shared_data_asc = addrspacecast ptr addrspace(3) @shared_data to ptr
121+
%iss2 = tail call i1 @llvm.nvvm.isspacep.shared(ptr %shared_data_asc)
122+
%iss28 = zext i1 %iss2 to i8
123+
store i8 %iss28, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1
124+
125+
%isc1 = tail call i1 @llvm.nvvm.isspacep.shared(ptr addrspacecast (ptr addrspace(4) @const_data to ptr))
126+
%isc18 = zext i1 %isc1 to i8
127+
store i8 %isc18, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1
128+
129+
%const_data_asc = addrspacecast ptr addrspace(4) @const_data to ptr
130+
%isc2 = tail call i1 @llvm.nvvm.isspacep.shared(ptr %const_data_asc)
131+
%isc28 = zext i1 %isc2 to i8
132+
store i8 %isc28, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1
133+
134+
; Local data can't have a constant address, so we can't have a constant ASC expression
135+
; We can only use an ASC instruction.
136+
%local_data_asc = addrspacecast ptr addrspace(5) %local_data to ptr
137+
%isl = call i1 @llvm.nvvm.isspacep.shared(ptr nonnull %local_data_asc)
138+
%isl8 = zext i1 %isl to i8
139+
store i8 %isl8, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1
140+
141+
ret void
142+
}
143+
144+
define dso_local void @check_const(ptr nocapture noundef readnone %out, ptr nocapture noundef readnone %generic_data, ptr addrspace(5) %local_data) local_unnamed_addr {
145+
; CHECK-LABEL: define dso_local void @check_const(
146+
; CHECK-SAME: ptr nocapture noundef readnone [[OUT:%.*]], ptr nocapture noundef readnone [[GENERIC_DATA:%.*]], ptr addrspace(5) [[LOCAL_DATA:%.*]]) local_unnamed_addr {
147+
; CHECK-NEXT: [[ENTRY:.*:]]
148+
; CHECK-NEXT: [[GEN0:%.*]] = tail call i1 @llvm.nvvm.isspacep.const(ptr [[GENERIC_DATA]])
149+
; CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[GEN0]] to i8
150+
; CHECK-NEXT: store i8 [[STOREDV]], ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1
151+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1
152+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1
153+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1
154+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1
155+
; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1
156+
; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1
157+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1
158+
; CHECK-NEXT: ret void
159+
;
160+
entry:
161+
; No constant folding for generic pointers of unknown origin.
162+
%gen0 = tail call i1 @llvm.nvvm.isspacep.const(ptr %generic_data)
163+
%storedv = zext i1 %gen0 to i8
164+
store i8 %storedv, ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1
165+
166+
%isg1 = tail call i1 @llvm.nvvm.isspacep.const(ptr addrspacecast (ptr addrspace(1) @global_data to ptr))
167+
%isg18 = zext i1 %isg1 to i8
168+
store i8 %isg18, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1
169+
170+
%global_data_asc = addrspacecast ptr addrspace(1) @global_data to ptr
171+
%isg2 = tail call i1 @llvm.nvvm.isspacep.const(ptr %global_data_asc)
172+
%isg28 = zext i1 %isg2 to i8
173+
store i8 %isg28, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1
174+
175+
%iss1 = tail call i1 @llvm.nvvm.isspacep.const(ptr addrspacecast (ptr addrspace(3) @shared_data to ptr))
176+
%iss18 = zext i1 %iss1 to i8
177+
store i8 %iss18, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1
178+
179+
%shared_data_asc = addrspacecast ptr addrspace(3) @shared_data to ptr
180+
%iss2 = tail call i1 @llvm.nvvm.isspacep.const(ptr %shared_data_asc)
181+
%iss28 = zext i1 %iss2 to i8
182+
store i8 %iss28, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1
183+
184+
%isc1 = tail call i1 @llvm.nvvm.isspacep.const(ptr addrspacecast (ptr addrspace(4) @const_data to ptr))
185+
%isc18 = zext i1 %isc1 to i8
186+
store i8 %isc18, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1
187+
188+
%const_data_asc = addrspacecast ptr addrspace(4) @const_data to ptr
189+
%isc2 = tail call i1 @llvm.nvvm.isspacep.const(ptr %const_data_asc)
190+
%isc28 = zext i1 %isc2 to i8
191+
store i8 %isc28, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1
192+
193+
; Local data can't have a constant address, so we can't have a constant ASC expression
194+
; We can only use an ASC instruction.
195+
%local_data_asc = addrspacecast ptr addrspace(5) %local_data to ptr
196+
%isl = call i1 @llvm.nvvm.isspacep.const(ptr nonnull %local_data_asc)
197+
%isl8 = zext i1 %isl to i8
198+
store i8 %isl8, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1
199+
200+
ret void
201+
}
202+
203+
define dso_local void @check_local(ptr nocapture noundef readnone %out, ptr nocapture noundef readnone %generic_data, ptr addrspace(5) %local_data) local_unnamed_addr {
204+
; CHECK-LABEL: define dso_local void @check_local(
205+
; CHECK-SAME: ptr nocapture noundef readnone [[OUT:%.*]], ptr nocapture noundef readnone [[GENERIC_DATA:%.*]], ptr addrspace(5) [[LOCAL_DATA:%.*]]) local_unnamed_addr {
206+
; CHECK-NEXT: [[ENTRY:.*:]]
207+
; CHECK-NEXT: [[GEN0:%.*]] = tail call i1 @llvm.nvvm.isspacep.local(ptr [[GENERIC_DATA]])
208+
; CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[GEN0]] to i8
209+
; CHECK-NEXT: store i8 [[STOREDV]], ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1
210+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1
211+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1
212+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1
213+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1
214+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1
215+
; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1
216+
; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1
217+
; CHECK-NEXT: ret void
218+
;
219+
entry:
220+
; No constant folding for generic pointers of unknown origin.
221+
%gen0 = tail call i1 @llvm.nvvm.isspacep.local(ptr %generic_data)
222+
%storedv = zext i1 %gen0 to i8
223+
store i8 %storedv, ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1
224+
225+
%isg1 = tail call i1 @llvm.nvvm.isspacep.local(ptr addrspacecast (ptr addrspace(1) @global_data to ptr))
226+
%isg18 = zext i1 %isg1 to i8
227+
store i8 %isg18, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1
228+
229+
%global_data_asc = addrspacecast ptr addrspace(1) @global_data to ptr
230+
%isg2 = tail call i1 @llvm.nvvm.isspacep.local(ptr %global_data_asc)
231+
%isg28 = zext i1 %isg2 to i8
232+
store i8 %isg28, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1
233+
234+
%iss1 = tail call i1 @llvm.nvvm.isspacep.local(ptr addrspacecast (ptr addrspace(3) @shared_data to ptr))
235+
%iss18 = zext i1 %iss1 to i8
236+
store i8 %iss18, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1
237+
238+
%shared_data_asc = addrspacecast ptr addrspace(3) @shared_data to ptr
239+
%iss2 = tail call i1 @llvm.nvvm.isspacep.local(ptr %shared_data_asc)
240+
%iss28 = zext i1 %iss2 to i8
241+
store i8 %iss28, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1
242+
243+
%isc1 = tail call i1 @llvm.nvvm.isspacep.local(ptr addrspacecast (ptr addrspace(4) @const_data to ptr))
244+
%isc18 = zext i1 %isc1 to i8
245+
store i8 %isc18, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1
246+
247+
%const_data_asc = addrspacecast ptr addrspace(4) @const_data to ptr
248+
%isc2 = tail call i1 @llvm.nvvm.isspacep.local(ptr %const_data_asc)
249+
%isc28 = zext i1 %isc2 to i8
250+
store i8 %isc28, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1
251+
252+
; Local data can't have a constant address, so we can't have a constant ASC expression
253+
; We can only use an ASC instruction.
254+
%local_data_asc = addrspacecast ptr addrspace(5) %local_data to ptr
255+
%isl = call i1 @llvm.nvvm.isspacep.local(ptr nonnull %local_data_asc)
256+
%isl8 = zext i1 %isl to i8
257+
store i8 %isl8, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1
258+
259+
ret void
260+
}
261+

0 commit comments

Comments
 (0)