| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: opt -mtriple=nvptx64-nvidia-cuda -passes=load-store-vectorizer -mcpu=sm_100 -mattr=+ptx88 -S -o - %s | FileCheck %s |
| |
| define void @test_redundant_no_gap(ptr addrspace(1) %ptr) { |
| ; CHECK-LABEL: define void @test_redundant_no_gap( |
| ; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0:[0-9]+]] { |
| ; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i32>, ptr addrspace(1) [[PTR]], align 32 |
| ; CHECK-NEXT: [[LD03:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> poison, <2 x i32> <i32 0, i32 1> |
| ; CHECK-NEXT: [[LD12:%.*]] = extractelement <8 x i32> [[TMP1]], i64 1 |
| ; CHECK-NEXT: [[LD25:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> poison, <2 x i32> <i32 2, i32 3> |
| ; CHECK-NEXT: [[LD37:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> poison, <2 x i32> <i32 4, i32 5> |
| ; CHECK-NEXT: [[LD45:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> poison, <2 x i32> <i32 6, i32 7> |
| ; CHECK-NEXT: ret void |
| ; |
| %ld0 = load <2 x i32>, ptr addrspace(1) %ptr, align 32 |
| %gep1 = getelementptr inbounds i8, ptr addrspace(1) %ptr, i32 4 |
| %ld1 = load i32, ptr addrspace(1) %gep1, align 4 |
| %gep2 = getelementptr inbounds i8, ptr addrspace(1) %ptr, i32 8 |
| %ld2 = load <2 x i32>, ptr addrspace(1) %gep2, align 8 |
| %gep3 = getelementptr inbounds i8, ptr addrspace(1) %ptr, i32 16 |
| %ld3 = load <2 x i32>, ptr addrspace(1) %gep3, align 16 |
| %gep4 = getelementptr inbounds i8, ptr addrspace(1) %ptr, i32 24 |
| %ld4 = load <2 x i32>, ptr addrspace(1) %gep4, align 8 |
| ret void |
| } |
| |
| ; This fills the 2-byte gap between ld0 and ld3. |
| ; ld1 is folded into the vector but ld0 is treated as the end of the chain |
| ; at the point when the gap is considered, because it reads further than ld1. |
| define void @test_redundant_gap(ptr addrspace(1) %ptr) { |
| ; CHECK-LABEL: define void @test_redundant_gap( |
| ; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i32> @llvm.masked.load.v8i32.p1(ptr addrspace(1) align 32 [[PTR]], <8 x i1> <i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 true, i1 true>, <8 x i32> poison) |
| ; CHECK-NEXT: [[LD01:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> poison, <2 x i32> <i32 0, i32 1> |
| ; CHECK-NEXT: [[LD12:%.*]] = extractelement <8 x i32> [[TMP1]], i64 0 |
| ; CHECK-NEXT: [[GAPFILL3:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> poison, <2 x i32> <i32 2, i32 3> |
| ; CHECK-NEXT: [[LD34:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> poison, <2 x i32> <i32 4, i32 5> |
| ; CHECK-NEXT: [[LD45:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> poison, <2 x i32> <i32 6, i32 7> |
| ; CHECK-NEXT: ret void |
| ; |
| %ld0 = load <2 x i32>, ptr addrspace(1) %ptr, align 32 |
| %ld1 = load i32, ptr addrspace(1) %ptr, align 4 |
| %gep3 = getelementptr inbounds i8, ptr addrspace(1) %ptr, i32 16 |
| %ld3 = load <2 x i32>, ptr addrspace(1) %gep3, align 16 |
| %gep4 = getelementptr inbounds i8, ptr addrspace(1) %ptr, i32 24 |
| %ld4 = load <2 x i32>, ptr addrspace(1) %gep4, align 8 |
| ret void |
| } |
| |
| ; This chain contains two elements, one before a gap, |
| ; and one before the end of the chain. Chain should be correctly extended. |
| define void @test_redundant_gap_and_extend(ptr addrspace(1) %ptr) { |
| ; CHECK-LABEL: define void @test_redundant_gap_and_extend( |
| ; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i32> @llvm.masked.load.v8i32.p1(ptr addrspace(1) align 32 [[PTR]], <8 x i1> <i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false>, <8 x i32> poison) |
| ; CHECK-NEXT: [[LD03:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> poison, <2 x i32> <i32 0, i32 1> |
| ; CHECK-NEXT: [[LD14:%.*]] = extractelement <8 x i32> [[TMP1]], i64 0 |
| ; CHECK-NEXT: [[GAPFILL5:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> poison, <2 x i32> <i32 2, i32 3> |
| ; CHECK-NEXT: [[LD36:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> poison, <2 x i32> <i32 4, i32 5> |
| ; CHECK-NEXT: [[LD47:%.*]] = extractelement <8 x i32> [[TMP1]], i64 4 |
| ; CHECK-NEXT: [[EXTEND8:%.*]] = extractelement <8 x i32> [[TMP1]], i64 6 |
| ; CHECK-NEXT: [[EXTEND29:%.*]] = extractelement <8 x i32> [[TMP1]], i64 7 |
| ; CHECK-NEXT: ret void |
| ; |
| %ld0 = load <2 x i32>, ptr addrspace(1) %ptr, align 32 |
| %ld1 = load i32, ptr addrspace(1) %ptr, align 4 |
| %gep3 = getelementptr inbounds i8, ptr addrspace(1) %ptr, i32 16 |
| %ld3 = load <2 x i32>, ptr addrspace(1) %gep3, align 16 |
| %ld4 = load i32, ptr addrspace(1) %gep3, align 4 |
| ret void |
| } |