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 3target datalayout = "e-i64:64-i128:128-v16:16-v32:32-n16:32:64" 4target 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 21declare i1 @llvm.nvvm.isspacep.global(ptr nocapture) 22declare i1 @llvm.nvvm.isspacep.shared(ptr nocapture) 23declare i1 @llvm.nvvm.isspacep.const(ptr nocapture) 24declare i1 @llvm.nvvm.isspacep.local(ptr nocapture) 25 26define dso_local void @check_global(ptr nocapture noundef readnone %out, ptr nocapture noundef readnone %genp, 27; CHECK-LABEL: define dso_local void @check_global( 28; CHECK-SAME: ptr noundef readnone captures(none) [[OUT:%.*]], ptr noundef readnone captures(none) [[GENP:%.*]], ptr addrspace(1) [[GP:%.*]], ptr addrspace(3) [[SP:%.*]], ptr addrspace(4) [[CP:%.*]], ptr addrspace(5) [[LP:%.*]]) local_unnamed_addr { 29; CHECK-NEXT: [[ENTRY:.*:]] 30; CHECK-NEXT: [[GEN0:%.*]] = tail call i1 @llvm.nvvm.isspacep.global(ptr [[GENP]]) 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 ptr addrspace(1) %gp, 43 ptr addrspace(3) %sp, 44 ptr addrspace(4) %cp, 45 ptr addrspace(5) %lp) local_unnamed_addr { 46entry: 47 ; No constant folding for generic pointers of unknown origin. 48 %gen0 = tail call i1 @llvm.nvvm.isspacep.global(ptr %genp) 49 %storedv = zext i1 %gen0 to i8 50 store i8 %storedv, ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1 51 52 %isg1 = tail call i1 @llvm.nvvm.isspacep.global(ptr addrspacecast (ptr addrspace(1) @global_data to ptr)) 53 %isg18 = zext i1 %isg1 to i8 54 store i8 %isg18, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1 55 56 %gp_asc = addrspacecast ptr addrspace(1) %gp to ptr 57 %isg2 = tail call i1 @llvm.nvvm.isspacep.global(ptr %gp_asc) 58 %isg28 = zext i1 %isg2 to i8 59 store i8 %isg28, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1 60 61 %iss1 = tail call i1 @llvm.nvvm.isspacep.global(ptr addrspacecast (ptr addrspace(3) @shared_data to ptr)) 62 %iss18 = zext i1 %iss1 to i8 63 store i8 %iss18, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1 64 65 %sp_asc = addrspacecast ptr addrspace(3) %sp to ptr 66 %iss2 = tail call i1 @llvm.nvvm.isspacep.global(ptr %sp_asc) 67 %iss28 = zext i1 %iss2 to i8 68 store i8 %iss28, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1 69 70 %isc1 = tail call i1 @llvm.nvvm.isspacep.global(ptr addrspacecast (ptr addrspace(4) @const_data to ptr)) 71 %isc18 = zext i1 %isc1 to i8 72 store i8 %isc18, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1 73 74 %cp_asc = addrspacecast ptr addrspace(4) %cp to ptr 75 %isc2 = tail call i1 @llvm.nvvm.isspacep.global(ptr %cp_asc) 76 %isc28 = zext i1 %isc2 to i8 77 store i8 %isc28, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1 78 79 ; Local data can't ihave a constant address, so we can't have a constant ASC expression 80 ; We can only use an ASC instruction. 81 %lp_asc = addrspacecast ptr addrspace(5) %lp to ptr 82 %isl = call i1 @llvm.nvvm.isspacep.global(ptr nonnull %lp_asc) 83 %isl8 = zext i1 %isl to i8 84 store i8 %isl8, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1 85 86 ret void 87} 88 89define dso_local void @check_shared(ptr nocapture noundef readnone %out, ptr nocapture noundef readnone %genp, 90; CHECK-LABEL: define dso_local void @check_shared( 91; CHECK-SAME: ptr noundef readnone captures(none) [[OUT:%.*]], ptr noundef readnone captures(none) [[GENP:%.*]], ptr addrspace(1) [[GP:%.*]], ptr addrspace(3) [[SP:%.*]], ptr addrspace(4) [[CP:%.*]], ptr addrspace(5) [[LP:%.*]]) local_unnamed_addr { 92; CHECK-NEXT: [[ENTRY:.*:]] 93; CHECK-NEXT: [[GEN0:%.*]] = tail call i1 @llvm.nvvm.isspacep.shared(ptr [[GENP]]) 94; CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[GEN0]] to i8 95; CHECK-NEXT: store i8 [[STOREDV]], ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1 96; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1 97; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1 98; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1 99; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1 100; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1 101; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1 102; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1 103; CHECK-NEXT: ret void 104; 105 ptr addrspace(1) %gp, 106 ptr addrspace(3) %sp, 107 ptr addrspace(4) %cp, 108 ptr addrspace(5) %lp) local_unnamed_addr { 109entry: 110 ; No constant folding for generic pointers of unknown origin. 111 %gen0 = tail call i1 @llvm.nvvm.isspacep.shared(ptr %genp) 112 %storedv = zext i1 %gen0 to i8 113 store i8 %storedv, ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1 114 115 %isg1 = tail call i1 @llvm.nvvm.isspacep.shared(ptr addrspacecast (ptr addrspace(1) @global_data to ptr)) 116 %isg18 = zext i1 %isg1 to i8 117 store i8 %isg18, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1 118 119 %gp_asc = addrspacecast ptr addrspace(1) %gp to ptr 120 %isg2 = tail call i1 @llvm.nvvm.isspacep.shared(ptr %gp_asc) 121 %isg28 = zext i1 %isg2 to i8 122 store i8 %isg28, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1 123 124 %iss1 = tail call i1 @llvm.nvvm.isspacep.shared(ptr addrspacecast (ptr addrspace(3) @shared_data to ptr)) 125 %iss18 = zext i1 %iss1 to i8 126 store i8 %iss18, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1 127 128 %sp_asc = addrspacecast ptr addrspace(3) %sp to ptr 129 %iss2 = tail call i1 @llvm.nvvm.isspacep.shared(ptr %sp_asc) 130 %iss28 = zext i1 %iss2 to i8 131 store i8 %iss28, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1 132 133 %isc1 = tail call i1 @llvm.nvvm.isspacep.shared(ptr addrspacecast (ptr addrspace(4) @const_data to ptr)) 134 %isc18 = zext i1 %isc1 to i8 135 store i8 %isc18, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1 136 137 %cp_asc = addrspacecast ptr addrspace(4) %cp to ptr 138 %isc2 = tail call i1 @llvm.nvvm.isspacep.shared(ptr %cp_asc) 139 %isc28 = zext i1 %isc2 to i8 140 store i8 %isc28, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1 141 142 ; Local data can't have a constant address, so we can't have a constant ASC expression 143 ; We can only use an ASC instruction. 144 %lp_asc = addrspacecast ptr addrspace(5) %lp to ptr 145 %isl = call i1 @llvm.nvvm.isspacep.shared(ptr nonnull %lp_asc) 146 %isl8 = zext i1 %isl to i8 147 store i8 %isl8, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1 148 149 ret void 150} 151 152define dso_local void @check_const(ptr nocapture noundef readnone %out, ptr nocapture noundef readnone %genp, 153; CHECK-LABEL: define dso_local void @check_const( 154; CHECK-SAME: ptr noundef readnone captures(none) [[OUT:%.*]], ptr noundef readnone captures(none) [[GENP:%.*]], ptr addrspace(1) [[GP:%.*]], ptr addrspace(3) [[SP:%.*]], ptr addrspace(4) [[CP:%.*]], ptr addrspace(5) [[LP:%.*]]) local_unnamed_addr { 155; CHECK-NEXT: [[ENTRY:.*:]] 156; CHECK-NEXT: [[GEN0:%.*]] = tail call i1 @llvm.nvvm.isspacep.const(ptr [[GENP]]) 157; CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[GEN0]] to i8 158; CHECK-NEXT: store i8 [[STOREDV]], ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1 159; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1 160; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1 161; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1 162; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1 163; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1 164; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1 165; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1 166; CHECK-NEXT: ret void 167; 168 ptr addrspace(1) %gp, 169 ptr addrspace(3) %sp, 170 ptr addrspace(4) %cp, 171 ptr addrspace(5) %lp) local_unnamed_addr { 172entry: 173 ; No constant folding for generic pointers of unknown origin. 174 %gen0 = tail call i1 @llvm.nvvm.isspacep.const(ptr %genp) 175 %storedv = zext i1 %gen0 to i8 176 store i8 %storedv, ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1 177 178 %isg1 = tail call i1 @llvm.nvvm.isspacep.const(ptr addrspacecast (ptr addrspace(1) @global_data to ptr)) 179 %isg18 = zext i1 %isg1 to i8 180 store i8 %isg18, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1 181 182 %gp_asc = addrspacecast ptr addrspace(1) %gp to ptr 183 %isg2 = tail call i1 @llvm.nvvm.isspacep.const(ptr %gp_asc) 184 %isg28 = zext i1 %isg2 to i8 185 store i8 %isg28, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1 186 187 %iss1 = tail call i1 @llvm.nvvm.isspacep.const(ptr addrspacecast (ptr addrspace(3) @shared_data to ptr)) 188 %iss18 = zext i1 %iss1 to i8 189 store i8 %iss18, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1 190 191 %sp_asc = addrspacecast ptr addrspace(3) %sp to ptr 192 %iss2 = tail call i1 @llvm.nvvm.isspacep.const(ptr %sp_asc) 193 %iss28 = zext i1 %iss2 to i8 194 store i8 %iss28, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1 195 196 %isc1 = tail call i1 @llvm.nvvm.isspacep.const(ptr addrspacecast (ptr addrspace(4) @const_data to ptr)) 197 %isc18 = zext i1 %isc1 to i8 198 store i8 %isc18, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1 199 200 %cp_asc = addrspacecast ptr addrspace(4) %cp to ptr 201 %isc2 = tail call i1 @llvm.nvvm.isspacep.const(ptr %cp_asc) 202 %isc28 = zext i1 %isc2 to i8 203 store i8 %isc28, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1 204 205 ; Local data can't have a constant address, so we can't have a constant ASC expression 206 ; We can only use an ASC instruction. 207 %lp_asc = addrspacecast ptr addrspace(5) %lp to ptr 208 %isl = call i1 @llvm.nvvm.isspacep.const(ptr nonnull %lp_asc) 209 %isl8 = zext i1 %isl to i8 210 store i8 %isl8, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1 211 212 ret void 213} 214 215define dso_local void @check_local(ptr nocapture noundef readnone %out, ptr nocapture noundef readnone %genp, 216; CHECK-LABEL: define dso_local void @check_local( 217; CHECK-SAME: ptr noundef readnone captures(none) [[OUT:%.*]], ptr noundef readnone captures(none) [[GENP:%.*]], ptr addrspace(1) [[GP:%.*]], ptr addrspace(3) [[SP:%.*]], ptr addrspace(4) [[CP:%.*]], ptr addrspace(5) [[LP:%.*]]) local_unnamed_addr { 218; CHECK-NEXT: [[ENTRY:.*:]] 219; CHECK-NEXT: [[GEN0:%.*]] = tail call i1 @llvm.nvvm.isspacep.local(ptr [[GENP]]) 220; CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[GEN0]] to i8 221; CHECK-NEXT: store i8 [[STOREDV]], ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1 222; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1 223; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1 224; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1 225; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1 226; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1 227; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1 228; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1 229; CHECK-NEXT: ret void 230; 231 ptr addrspace(1) %gp, 232 ptr addrspace(3) %sp, 233 ptr addrspace(4) %cp, 234 ptr addrspace(5) %lp) local_unnamed_addr { 235entry: 236 ; No constant folding for generic pointers of unknown origin. 237 %gen0 = tail call i1 @llvm.nvvm.isspacep.local(ptr %genp) 238 %storedv = zext i1 %gen0 to i8 239 store i8 %storedv, ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1 240 241 %isg1 = tail call i1 @llvm.nvvm.isspacep.local(ptr addrspacecast (ptr addrspace(1) @global_data to ptr)) 242 %isg18 = zext i1 %isg1 to i8 243 store i8 %isg18, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1 244 245 %gp_asc = addrspacecast ptr addrspace(1) %gp to ptr 246 %isg2 = tail call i1 @llvm.nvvm.isspacep.local(ptr %gp_asc) 247 %isg28 = zext i1 %isg2 to i8 248 store i8 %isg28, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1 249 250 %iss1 = tail call i1 @llvm.nvvm.isspacep.local(ptr addrspacecast (ptr addrspace(3) @shared_data to ptr)) 251 %iss18 = zext i1 %iss1 to i8 252 store i8 %iss18, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1 253 254 %sp_asc = addrspacecast ptr addrspace(3) %sp to ptr 255 %iss2 = tail call i1 @llvm.nvvm.isspacep.local(ptr %sp_asc) 256 %iss28 = zext i1 %iss2 to i8 257 store i8 %iss28, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1 258 259 %isc1 = tail call i1 @llvm.nvvm.isspacep.local(ptr addrspacecast (ptr addrspace(4) @const_data to ptr)) 260 %isc18 = zext i1 %isc1 to i8 261 store i8 %isc18, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1 262 263 %cp_asc = addrspacecast ptr addrspace(4) %cp to ptr 264 %isc2 = tail call i1 @llvm.nvvm.isspacep.local(ptr %cp_asc) 265 %isc28 = zext i1 %isc2 to i8 266 store i8 %isc28, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1 267 268 ; Local data can't have a constant address, so we can't have a constant ASC expression 269 ; We can only use an ASC instruction. 270 %lp_asc = addrspacecast ptr addrspace(5) %lp to ptr 271 %isl = call i1 @llvm.nvvm.isspacep.local(ptr nonnull %lp_asc) 272 %isl8 = zext i1 %isl to i8 273 store i8 %isl8, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1 274 275 ret void 276} 277 278