| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 |
| ; RUN: opt < %s -passes=instcombine -mtriple=nvptx64-nvidia-cuda -S | FileCheck %s |
| target datalayout = "e-i64:64-i128:128-v16:16-v32:32-n16:32:64" |
| target triple = "nvptx64-nvidia-cuda" |
| |
| ; Source data in different AS. |
| @shared_data = dso_local addrspace(3) global i32 undef, align 4 |
| @global_data = dso_local addrspace(1) externally_initialized global i32 0, align 4 |
| @const_data = dso_local addrspace(4) externally_initialized constant i32 3, align 4 |
| |
| ; Results get stored here. |
| @gen = dso_local addrspace(1) externally_initialized global i8 0, align 1 |
| @g1 = dso_local addrspace(1) externally_initialized global i8 0, align 1 |
| @g2 = dso_local addrspace(1) externally_initialized global i8 0, align 1 |
| @s1 = dso_local addrspace(1) externally_initialized global i8 0, align 1 |
| @s2 = dso_local addrspace(1) externally_initialized global i8 0, align 1 |
| @c1 = dso_local addrspace(1) externally_initialized global i8 0, align 1 |
| @c2 = dso_local addrspace(1) externally_initialized global i8 0, align 1 |
| @l = dso_local addrspace(1) externally_initialized global i8 0, align 1 |
| |
| declare i1 @llvm.nvvm.isspacep.global(ptr nocapture) |
| declare i1 @llvm.nvvm.isspacep.shared(ptr nocapture) |
| declare i1 @llvm.nvvm.isspacep.const(ptr nocapture) |
| declare i1 @llvm.nvvm.isspacep.local(ptr nocapture) |
| |
| define dso_local void @check_global(ptr nocapture noundef readnone %out, ptr nocapture noundef readnone %genp, |
| ; CHECK-LABEL: define dso_local void @check_global( |
| ; CHECK-SAME: ptr nocapture noundef readnone [[OUT:%.*]], ptr nocapture noundef readnone [[GENP:%.*]], ptr addrspace(1) [[GP:%.*]], ptr addrspace(3) [[SP:%.*]], ptr addrspace(4) [[CP:%.*]], ptr addrspace(5) [[LP:%.*]]) local_unnamed_addr { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[GEN0:%.*]] = tail call i1 @llvm.nvvm.isspacep.global(ptr [[GENP]]) |
| ; CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[GEN0]] to i8 |
| ; CHECK-NEXT: store i8 [[STOREDV]], ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1 |
| ; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1 |
| ; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1 |
| ; CHECK-NEXT: ret void |
| ; |
| ptr addrspace(1) %gp, |
| ptr addrspace(3) %sp, |
| ptr addrspace(4) %cp, |
| ptr addrspace(5) %lp) local_unnamed_addr { |
| entry: |
| ; No constant folding for generic pointers of unknown origin. |
| %gen0 = tail call i1 @llvm.nvvm.isspacep.global(ptr %genp) |
| %storedv = zext i1 %gen0 to i8 |
| store i8 %storedv, ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1 |
| |
| %isg1 = tail call i1 @llvm.nvvm.isspacep.global(ptr addrspacecast (ptr addrspace(1) @global_data to ptr)) |
| %isg18 = zext i1 %isg1 to i8 |
| store i8 %isg18, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1 |
| |
| %gp_asc = addrspacecast ptr addrspace(1) %gp to ptr |
| %isg2 = tail call i1 @llvm.nvvm.isspacep.global(ptr %gp_asc) |
| %isg28 = zext i1 %isg2 to i8 |
| store i8 %isg28, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1 |
| |
| %iss1 = tail call i1 @llvm.nvvm.isspacep.global(ptr addrspacecast (ptr addrspace(3) @shared_data to ptr)) |
| %iss18 = zext i1 %iss1 to i8 |
| store i8 %iss18, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1 |
| |
| %sp_asc = addrspacecast ptr addrspace(3) %sp to ptr |
| %iss2 = tail call i1 @llvm.nvvm.isspacep.global(ptr %sp_asc) |
| %iss28 = zext i1 %iss2 to i8 |
| store i8 %iss28, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1 |
| |
| %isc1 = tail call i1 @llvm.nvvm.isspacep.global(ptr addrspacecast (ptr addrspace(4) @const_data to ptr)) |
| %isc18 = zext i1 %isc1 to i8 |
| store i8 %isc18, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1 |
| |
| %cp_asc = addrspacecast ptr addrspace(4) %cp to ptr |
| %isc2 = tail call i1 @llvm.nvvm.isspacep.global(ptr %cp_asc) |
| %isc28 = zext i1 %isc2 to i8 |
| store i8 %isc28, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1 |
| |
| ; Local data can't ihave a constant address, so we can't have a constant ASC expression |
| ; We can only use an ASC instruction. |
| %lp_asc = addrspacecast ptr addrspace(5) %lp to ptr |
| %isl = call i1 @llvm.nvvm.isspacep.global(ptr nonnull %lp_asc) |
| %isl8 = zext i1 %isl to i8 |
| store i8 %isl8, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1 |
| |
| ret void |
| } |
| |
| define dso_local void @check_shared(ptr nocapture noundef readnone %out, ptr nocapture noundef readnone %genp, |
| ; CHECK-LABEL: define dso_local void @check_shared( |
| ; CHECK-SAME: ptr nocapture noundef readnone [[OUT:%.*]], ptr nocapture noundef readnone [[GENP:%.*]], ptr addrspace(1) [[GP:%.*]], ptr addrspace(3) [[SP:%.*]], ptr addrspace(4) [[CP:%.*]], ptr addrspace(5) [[LP:%.*]]) local_unnamed_addr { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[GEN0:%.*]] = tail call i1 @llvm.nvvm.isspacep.shared(ptr [[GENP]]) |
| ; CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[GEN0]] to i8 |
| ; CHECK-NEXT: store i8 [[STOREDV]], ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1 |
| ; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1 |
| ; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1 |
| ; CHECK-NEXT: ret void |
| ; |
| ptr addrspace(1) %gp, |
| ptr addrspace(3) %sp, |
| ptr addrspace(4) %cp, |
| ptr addrspace(5) %lp) local_unnamed_addr { |
| entry: |
| ; No constant folding for generic pointers of unknown origin. |
| %gen0 = tail call i1 @llvm.nvvm.isspacep.shared(ptr %genp) |
| %storedv = zext i1 %gen0 to i8 |
| store i8 %storedv, ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1 |
| |
| %isg1 = tail call i1 @llvm.nvvm.isspacep.shared(ptr addrspacecast (ptr addrspace(1) @global_data to ptr)) |
| %isg18 = zext i1 %isg1 to i8 |
| store i8 %isg18, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1 |
| |
| %gp_asc = addrspacecast ptr addrspace(1) %gp to ptr |
| %isg2 = tail call i1 @llvm.nvvm.isspacep.shared(ptr %gp_asc) |
| %isg28 = zext i1 %isg2 to i8 |
| store i8 %isg28, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1 |
| |
| %iss1 = tail call i1 @llvm.nvvm.isspacep.shared(ptr addrspacecast (ptr addrspace(3) @shared_data to ptr)) |
| %iss18 = zext i1 %iss1 to i8 |
| store i8 %iss18, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1 |
| |
| %sp_asc = addrspacecast ptr addrspace(3) %sp to ptr |
| %iss2 = tail call i1 @llvm.nvvm.isspacep.shared(ptr %sp_asc) |
| %iss28 = zext i1 %iss2 to i8 |
| store i8 %iss28, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1 |
| |
| %isc1 = tail call i1 @llvm.nvvm.isspacep.shared(ptr addrspacecast (ptr addrspace(4) @const_data to ptr)) |
| %isc18 = zext i1 %isc1 to i8 |
| store i8 %isc18, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1 |
| |
| %cp_asc = addrspacecast ptr addrspace(4) %cp to ptr |
| %isc2 = tail call i1 @llvm.nvvm.isspacep.shared(ptr %cp_asc) |
| %isc28 = zext i1 %isc2 to i8 |
| store i8 %isc28, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1 |
| |
| ; Local data can't have a constant address, so we can't have a constant ASC expression |
| ; We can only use an ASC instruction. |
| %lp_asc = addrspacecast ptr addrspace(5) %lp to ptr |
| %isl = call i1 @llvm.nvvm.isspacep.shared(ptr nonnull %lp_asc) |
| %isl8 = zext i1 %isl to i8 |
| store i8 %isl8, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1 |
| |
| ret void |
| } |
| |
| define dso_local void @check_const(ptr nocapture noundef readnone %out, ptr nocapture noundef readnone %genp, |
| ; CHECK-LABEL: define dso_local void @check_const( |
| ; CHECK-SAME: ptr nocapture noundef readnone [[OUT:%.*]], ptr nocapture noundef readnone [[GENP:%.*]], ptr addrspace(1) [[GP:%.*]], ptr addrspace(3) [[SP:%.*]], ptr addrspace(4) [[CP:%.*]], ptr addrspace(5) [[LP:%.*]]) local_unnamed_addr { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[GEN0:%.*]] = tail call i1 @llvm.nvvm.isspacep.const(ptr [[GENP]]) |
| ; CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[GEN0]] to i8 |
| ; CHECK-NEXT: store i8 [[STOREDV]], ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1 |
| ; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1 |
| ; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1 |
| ; CHECK-NEXT: ret void |
| ; |
| ptr addrspace(1) %gp, |
| ptr addrspace(3) %sp, |
| ptr addrspace(4) %cp, |
| ptr addrspace(5) %lp) local_unnamed_addr { |
| entry: |
| ; No constant folding for generic pointers of unknown origin. |
| %gen0 = tail call i1 @llvm.nvvm.isspacep.const(ptr %genp) |
| %storedv = zext i1 %gen0 to i8 |
| store i8 %storedv, ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1 |
| |
| %isg1 = tail call i1 @llvm.nvvm.isspacep.const(ptr addrspacecast (ptr addrspace(1) @global_data to ptr)) |
| %isg18 = zext i1 %isg1 to i8 |
| store i8 %isg18, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1 |
| |
| %gp_asc = addrspacecast ptr addrspace(1) %gp to ptr |
| %isg2 = tail call i1 @llvm.nvvm.isspacep.const(ptr %gp_asc) |
| %isg28 = zext i1 %isg2 to i8 |
| store i8 %isg28, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1 |
| |
| %iss1 = tail call i1 @llvm.nvvm.isspacep.const(ptr addrspacecast (ptr addrspace(3) @shared_data to ptr)) |
| %iss18 = zext i1 %iss1 to i8 |
| store i8 %iss18, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1 |
| |
| %sp_asc = addrspacecast ptr addrspace(3) %sp to ptr |
| %iss2 = tail call i1 @llvm.nvvm.isspacep.const(ptr %sp_asc) |
| %iss28 = zext i1 %iss2 to i8 |
| store i8 %iss28, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1 |
| |
| %isc1 = tail call i1 @llvm.nvvm.isspacep.const(ptr addrspacecast (ptr addrspace(4) @const_data to ptr)) |
| %isc18 = zext i1 %isc1 to i8 |
| store i8 %isc18, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1 |
| |
| %cp_asc = addrspacecast ptr addrspace(4) %cp to ptr |
| %isc2 = tail call i1 @llvm.nvvm.isspacep.const(ptr %cp_asc) |
| %isc28 = zext i1 %isc2 to i8 |
| store i8 %isc28, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1 |
| |
| ; Local data can't have a constant address, so we can't have a constant ASC expression |
| ; We can only use an ASC instruction. |
| %lp_asc = addrspacecast ptr addrspace(5) %lp to ptr |
| %isl = call i1 @llvm.nvvm.isspacep.const(ptr nonnull %lp_asc) |
| %isl8 = zext i1 %isl to i8 |
| store i8 %isl8, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1 |
| |
| ret void |
| } |
| |
| define dso_local void @check_local(ptr nocapture noundef readnone %out, ptr nocapture noundef readnone %genp, |
| ; CHECK-LABEL: define dso_local void @check_local( |
| ; CHECK-SAME: ptr nocapture noundef readnone [[OUT:%.*]], ptr nocapture noundef readnone [[GENP:%.*]], ptr addrspace(1) [[GP:%.*]], ptr addrspace(3) [[SP:%.*]], ptr addrspace(4) [[CP:%.*]], ptr addrspace(5) [[LP:%.*]]) local_unnamed_addr { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[GEN0:%.*]] = tail call i1 @llvm.nvvm.isspacep.local(ptr [[GENP]]) |
| ; CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[GEN0]] to i8 |
| ; CHECK-NEXT: store i8 [[STOREDV]], ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1 |
| ; CHECK-NEXT: store i8 0, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1 |
| ; CHECK-NEXT: store i8 1, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1 |
| ; CHECK-NEXT: ret void |
| ; |
| ptr addrspace(1) %gp, |
| ptr addrspace(3) %sp, |
| ptr addrspace(4) %cp, |
| ptr addrspace(5) %lp) local_unnamed_addr { |
| entry: |
| ; No constant folding for generic pointers of unknown origin. |
| %gen0 = tail call i1 @llvm.nvvm.isspacep.local(ptr %genp) |
| %storedv = zext i1 %gen0 to i8 |
| store i8 %storedv, ptr addrspacecast (ptr addrspace(1) @gen to ptr), align 1 |
| |
| %isg1 = tail call i1 @llvm.nvvm.isspacep.local(ptr addrspacecast (ptr addrspace(1) @global_data to ptr)) |
| %isg18 = zext i1 %isg1 to i8 |
| store i8 %isg18, ptr addrspacecast (ptr addrspace(1) @g1 to ptr), align 1 |
| |
| %gp_asc = addrspacecast ptr addrspace(1) %gp to ptr |
| %isg2 = tail call i1 @llvm.nvvm.isspacep.local(ptr %gp_asc) |
| %isg28 = zext i1 %isg2 to i8 |
| store i8 %isg28, ptr addrspacecast (ptr addrspace(1) @g2 to ptr), align 1 |
| |
| %iss1 = tail call i1 @llvm.nvvm.isspacep.local(ptr addrspacecast (ptr addrspace(3) @shared_data to ptr)) |
| %iss18 = zext i1 %iss1 to i8 |
| store i8 %iss18, ptr addrspacecast (ptr addrspace(1) @s1 to ptr), align 1 |
| |
| %sp_asc = addrspacecast ptr addrspace(3) %sp to ptr |
| %iss2 = tail call i1 @llvm.nvvm.isspacep.local(ptr %sp_asc) |
| %iss28 = zext i1 %iss2 to i8 |
| store i8 %iss28, ptr addrspacecast (ptr addrspace(1) @s2 to ptr), align 1 |
| |
| %isc1 = tail call i1 @llvm.nvvm.isspacep.local(ptr addrspacecast (ptr addrspace(4) @const_data to ptr)) |
| %isc18 = zext i1 %isc1 to i8 |
| store i8 %isc18, ptr addrspacecast (ptr addrspace(1) @c1 to ptr), align 1 |
| |
| %cp_asc = addrspacecast ptr addrspace(4) %cp to ptr |
| %isc2 = tail call i1 @llvm.nvvm.isspacep.local(ptr %cp_asc) |
| %isc28 = zext i1 %isc2 to i8 |
| store i8 %isc28, ptr addrspacecast (ptr addrspace(1) @c2 to ptr), align 1 |
| |
| ; Local data can't have a constant address, so we can't have a constant ASC expression |
| ; We can only use an ASC instruction. |
| %lp_asc = addrspacecast ptr addrspace(5) %lp to ptr |
| %isl = call i1 @llvm.nvvm.isspacep.local(ptr nonnull %lp_asc) |
| %isl8 = zext i1 %isl to i8 |
| store i8 %isl8, ptr addrspacecast (ptr addrspace(1) @l to ptr), align 1 |
| |
| ret void |
| } |
| |