| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt -mtriple=wasm32 -mattr=+simd128 -passes=slp-vectorizer -S %s | FileCheck %s --check-prefix=SIMD128 |
| ; RUN: opt -mtriple=wasm32 -passes=slp-vectorizer -S %s | FileCheck %s --check-prefix=NO-SIMD128 |
| |
| ; Test that the SLP vectorizer correctly handles splat patterns when |
| ; shuffle costs are properly modeled for WebAssembly SIMD128. |
| |
| define void @splat_i8x16(i8 %v, ptr noalias %p) { |
| ; SIMD128-LABEL: @splat_i8x16( |
| ; SIMD128-NEXT: entry: |
| ; SIMD128-NEXT: [[TMP0:%.*]] = insertelement <16 x i8> poison, i8 [[V:%.*]], i32 0 |
| ; SIMD128-NEXT: [[TMP1:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <16 x i32> zeroinitializer |
| ; SIMD128-NEXT: store <16 x i8> [[TMP1]], ptr [[P:%.*]], align 1 |
| ; SIMD128-NEXT: ret void |
| ; |
| ; NO-SIMD128-LABEL: @splat_i8x16( |
| ; NO-SIMD128-NEXT: entry: |
| ; NO-SIMD128-NEXT: store i8 [[V:%.*]], ptr [[P:%.*]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 1 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX1]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 2 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX2]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX3:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 3 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX3]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 4 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX4]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX5:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 5 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX5]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX6:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 6 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX6]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX7:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 7 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX7]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX8:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 8 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX8]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX9:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 9 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX9]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX10:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 10 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX10]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX11:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 11 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX11]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX12:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 12 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX12]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX13:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 13 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX13]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX14:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 14 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX14]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX15:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 15 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX15]], align 1 |
| ; NO-SIMD128-NEXT: ret void |
| ; |
| entry: |
| store i8 %v, ptr %p, align 1 |
| %idx1 = getelementptr inbounds nuw i8, ptr %p, i32 1 |
| store i8 %v, ptr %idx1, align 1 |
| %idx2 = getelementptr inbounds nuw i8, ptr %p, i32 2 |
| store i8 %v, ptr %idx2, align 1 |
| %idx3 = getelementptr inbounds nuw i8, ptr %p, i32 3 |
| store i8 %v, ptr %idx3, align 1 |
| %idx4 = getelementptr inbounds nuw i8, ptr %p, i32 4 |
| store i8 %v, ptr %idx4, align 1 |
| %idx5 = getelementptr inbounds nuw i8, ptr %p, i32 5 |
| store i8 %v, ptr %idx5, align 1 |
| %idx6 = getelementptr inbounds nuw i8, ptr %p, i32 6 |
| store i8 %v, ptr %idx6, align 1 |
| %idx7 = getelementptr inbounds nuw i8, ptr %p, i32 7 |
| store i8 %v, ptr %idx7, align 1 |
| %idx8 = getelementptr inbounds nuw i8, ptr %p, i32 8 |
| store i8 %v, ptr %idx8, align 1 |
| %idx9 = getelementptr inbounds nuw i8, ptr %p, i32 9 |
| store i8 %v, ptr %idx9, align 1 |
| %idx10 = getelementptr inbounds nuw i8, ptr %p, i32 10 |
| store i8 %v, ptr %idx10, align 1 |
| %idx11 = getelementptr inbounds nuw i8, ptr %p, i32 11 |
| store i8 %v, ptr %idx11, align 1 |
| %idx12 = getelementptr inbounds nuw i8, ptr %p, i32 12 |
| store i8 %v, ptr %idx12, align 1 |
| %idx13 = getelementptr inbounds nuw i8, ptr %p, i32 13 |
| store i8 %v, ptr %idx13, align 1 |
| %idx14 = getelementptr inbounds nuw i8, ptr %p, i32 14 |
| store i8 %v, ptr %idx14, align 1 |
| %idx15 = getelementptr inbounds nuw i8, ptr %p, i32 15 |
| store i8 %v, ptr %idx15, align 1 |
| ret void |
| } |
| |
| define void @splat_i16x8(i16 %v, ptr noalias %p) { |
| ; SIMD128-LABEL: @splat_i16x8( |
| ; SIMD128-NEXT: entry: |
| ; SIMD128-NEXT: [[TMP0:%.*]] = insertelement <8 x i16> poison, i16 [[V:%.*]], i32 0 |
| ; SIMD128-NEXT: [[TMP1:%.*]] = shufflevector <8 x i16> [[TMP0]], <8 x i16> poison, <8 x i32> zeroinitializer |
| ; SIMD128-NEXT: store <8 x i16> [[TMP1]], ptr [[P:%.*]], align 1 |
| ; SIMD128-NEXT: ret void |
| ; |
| ; NO-SIMD128-LABEL: @splat_i16x8( |
| ; NO-SIMD128-NEXT: entry: |
| ; NO-SIMD128-NEXT: store i16 [[V:%.*]], ptr [[P:%.*]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 2 |
| ; NO-SIMD128-NEXT: store i16 [[V]], ptr [[IDX1]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 4 |
| ; NO-SIMD128-NEXT: store i16 [[V]], ptr [[IDX2]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX3:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 6 |
| ; NO-SIMD128-NEXT: store i16 [[V]], ptr [[IDX3]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 8 |
| ; NO-SIMD128-NEXT: store i16 [[V]], ptr [[IDX4]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX5:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 10 |
| ; NO-SIMD128-NEXT: store i16 [[V]], ptr [[IDX5]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX6:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 12 |
| ; NO-SIMD128-NEXT: store i16 [[V]], ptr [[IDX6]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX7:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 14 |
| ; NO-SIMD128-NEXT: store i16 [[V]], ptr [[IDX7]], align 1 |
| ; NO-SIMD128-NEXT: ret void |
| ; |
| entry: |
| store i16 %v, ptr %p, align 1 |
| %idx1 = getelementptr inbounds nuw i8, ptr %p, i32 2 |
| store i16 %v, ptr %idx1, align 1 |
| %idx2 = getelementptr inbounds nuw i8, ptr %p, i32 4 |
| store i16 %v, ptr %idx2, align 1 |
| %idx3 = getelementptr inbounds nuw i8, ptr %p, i32 6 |
| store i16 %v, ptr %idx3, align 1 |
| %idx4 = getelementptr inbounds nuw i8, ptr %p, i32 8 |
| store i16 %v, ptr %idx4, align 1 |
| %idx5 = getelementptr inbounds nuw i8, ptr %p, i32 10 |
| store i16 %v, ptr %idx5, align 1 |
| %idx6 = getelementptr inbounds nuw i8, ptr %p, i32 12 |
| store i16 %v, ptr %idx6, align 1 |
| %idx7 = getelementptr inbounds nuw i8, ptr %p, i32 14 |
| store i16 %v, ptr %idx7, align 1 |
| ret void |
| } |
| |
| define void @splat_i32x4(i32 %v, ptr noalias %p) { |
| ; SIMD128-LABEL: @splat_i32x4( |
| ; SIMD128-NEXT: entry: |
| ; SIMD128-NEXT: store i32 [[V:%.*]], ptr [[P:%.*]], align 1 |
| ; SIMD128-NEXT: [[IDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 4 |
| ; SIMD128-NEXT: store i32 [[V]], ptr [[IDX1]], align 1 |
| ; SIMD128-NEXT: [[IDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 8 |
| ; SIMD128-NEXT: store i32 [[V]], ptr [[IDX2]], align 1 |
| ; SIMD128-NEXT: [[IDX3:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 12 |
| ; SIMD128-NEXT: store i32 [[V]], ptr [[IDX3]], align 1 |
| ; SIMD128-NEXT: ret void |
| ; |
| ; NO-SIMD128-LABEL: @splat_i32x4( |
| ; NO-SIMD128-NEXT: entry: |
| ; NO-SIMD128-NEXT: store i32 [[V:%.*]], ptr [[P:%.*]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 4 |
| ; NO-SIMD128-NEXT: store i32 [[V]], ptr [[IDX2]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 8 |
| ; NO-SIMD128-NEXT: store i32 [[V]], ptr [[IDX4]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX3:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 12 |
| ; NO-SIMD128-NEXT: store i32 [[V]], ptr [[IDX3]], align 1 |
| ; NO-SIMD128-NEXT: ret void |
| ; |
| entry: |
| store i32 %v, ptr %p, align 1 |
| %idx1 = getelementptr inbounds nuw i8, ptr %p, i32 4 |
| store i32 %v, ptr %idx1, align 1 |
| %idx2 = getelementptr inbounds nuw i8, ptr %p, i32 8 |
| store i32 %v, ptr %idx2, align 1 |
| %idx3 = getelementptr inbounds nuw i8, ptr %p, i32 12 |
| store i32 %v, ptr %idx3, align 1 |
| ret void |
| } |
| |
| |
| define void @splat_i64x2(i64 %v, ptr noalias %p) { |
| ; SIMD128-LABEL: @splat_i64x2( |
| ; SIMD128-NEXT: entry: |
| ; SIMD128-NEXT: store i64 [[V:%.*]], ptr [[P:%.*]], align 1 |
| ; SIMD128-NEXT: [[IDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 8 |
| ; SIMD128-NEXT: store i64 [[V]], ptr [[IDX1]], align 1 |
| ; SIMD128-NEXT: ret void |
| ; |
| ; NO-SIMD128-LABEL: @splat_i64x2( |
| ; NO-SIMD128-NEXT: entry: |
| ; NO-SIMD128-NEXT: store i64 [[V:%.*]], ptr [[P:%.*]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 8 |
| ; NO-SIMD128-NEXT: store i64 [[V]], ptr [[IDX1]], align 1 |
| ; NO-SIMD128-NEXT: ret void |
| ; |
| entry: |
| store i64 %v, ptr %p, align 1 |
| %idx1 = getelementptr inbounds nuw i8, ptr %p, i32 8 |
| store i64 %v, ptr %idx1, align 1 |
| ret void |
| } |
| |
| define void @splat_f32x4(float %v, ptr noalias %p) { |
| ; SIMD128-LABEL: @splat_f32x4( |
| ; SIMD128-NEXT: entry: |
| ; SIMD128-NEXT: store float [[V:%.*]], ptr [[P:%.*]], align 1 |
| ; SIMD128-NEXT: [[IDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 4 |
| ; SIMD128-NEXT: store float [[V]], ptr [[IDX1]], align 1 |
| ; SIMD128-NEXT: [[IDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 8 |
| ; SIMD128-NEXT: store float [[V]], ptr [[IDX2]], align 1 |
| ; SIMD128-NEXT: [[IDX3:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 12 |
| ; SIMD128-NEXT: store float [[V]], ptr [[IDX3]], align 1 |
| ; SIMD128-NEXT: ret void |
| ; |
| ; NO-SIMD128-LABEL: @splat_f32x4( |
| ; NO-SIMD128-NEXT: entry: |
| ; NO-SIMD128-NEXT: store float [[V:%.*]], ptr [[P:%.*]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 4 |
| ; NO-SIMD128-NEXT: store float [[V]], ptr [[IDX1]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 8 |
| ; NO-SIMD128-NEXT: store float [[V]], ptr [[IDX2]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX3:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 12 |
| ; NO-SIMD128-NEXT: store float [[V]], ptr [[IDX3]], align 1 |
| ; NO-SIMD128-NEXT: ret void |
| ; |
| entry: |
| store float %v, ptr %p, align 1 |
| %idx1 = getelementptr inbounds nuw i8, ptr %p, i32 4 |
| store float %v, ptr %idx1, align 1 |
| %idx2 = getelementptr inbounds nuw i8, ptr %p, i32 8 |
| store float %v, ptr %idx2, align 1 |
| %idx3 = getelementptr inbounds nuw i8, ptr %p, i32 12 |
| store float %v, ptr %idx3, align 1 |
| ret void |
| } |
| |
| define void @splat_f64x2(double %v, ptr noalias %p) { |
| ; SIMD128-LABEL: @splat_f64x2( |
| ; SIMD128-NEXT: entry: |
| ; SIMD128-NEXT: store double [[V:%.*]], ptr [[P:%.*]], align 1 |
| ; SIMD128-NEXT: [[IDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 8 |
| ; SIMD128-NEXT: store double [[V]], ptr [[IDX1]], align 1 |
| ; SIMD128-NEXT: ret void |
| ; |
| ; NO-SIMD128-LABEL: @splat_f64x2( |
| ; NO-SIMD128-NEXT: entry: |
| ; NO-SIMD128-NEXT: store double [[V:%.*]], ptr [[P:%.*]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 8 |
| ; NO-SIMD128-NEXT: store double [[V]], ptr [[IDX1]], align 1 |
| ; NO-SIMD128-NEXT: ret void |
| ; |
| entry: |
| store double %v, ptr %p, align 1 |
| %idx1 = getelementptr inbounds nuw i8, ptr %p, i32 8 |
| store double %v, ptr %idx1, align 1 |
| ret void |
| } |
| |
| define void @splat_i32x8(i32 %v, ptr noalias %p) { |
| ; SIMD128-LABEL: @splat_i32x8( |
| ; SIMD128-NEXT: entry: |
| ; SIMD128-NEXT: [[TMP0:%.*]] = insertelement <8 x i32> poison, i32 [[V:%.*]], i32 0 |
| ; SIMD128-NEXT: [[TMP1:%.*]] = shufflevector <8 x i32> [[TMP0]], <8 x i32> poison, <8 x i32> zeroinitializer |
| ; SIMD128-NEXT: store <8 x i32> [[TMP1]], ptr [[P:%.*]], align 1 |
| ; SIMD128-NEXT: ret void |
| ; |
| ; NO-SIMD128-LABEL: @splat_i32x8( |
| ; NO-SIMD128-NEXT: entry: |
| ; NO-SIMD128-NEXT: store i32 [[V:%.*]], ptr [[P:%.*]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 4 |
| ; NO-SIMD128-NEXT: store i32 [[V]], ptr [[IDX1]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 8 |
| ; NO-SIMD128-NEXT: store i32 [[V]], ptr [[IDX2]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX3:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 12 |
| ; NO-SIMD128-NEXT: store i32 [[V]], ptr [[IDX3]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 16 |
| ; NO-SIMD128-NEXT: store i32 [[V]], ptr [[IDX4]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX5:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 20 |
| ; NO-SIMD128-NEXT: store i32 [[V]], ptr [[IDX5]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX6:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 24 |
| ; NO-SIMD128-NEXT: store i32 [[V]], ptr [[IDX6]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX7:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 28 |
| ; NO-SIMD128-NEXT: store i32 [[V]], ptr [[IDX7]], align 1 |
| ; NO-SIMD128-NEXT: ret void |
| ; |
| entry: |
| store i32 %v, ptr %p, align 1 |
| %idx1 = getelementptr inbounds nuw i8, ptr %p, i32 4 |
| store i32 %v, ptr %idx1, align 1 |
| %idx2 = getelementptr inbounds nuw i8, ptr %p, i32 8 |
| store i32 %v, ptr %idx2, align 1 |
| %idx3 = getelementptr inbounds nuw i8, ptr %p, i32 12 |
| store i32 %v, ptr %idx3, align 1 |
| %idx4 = getelementptr inbounds nuw i8, ptr %p, i32 16 |
| store i32 %v, ptr %idx4, align 1 |
| %idx5 = getelementptr inbounds nuw i8, ptr %p, i32 20 |
| store i32 %v, ptr %idx5, align 1 |
| %idx6 = getelementptr inbounds nuw i8, ptr %p, i32 24 |
| store i32 %v, ptr %idx6, align 1 |
| %idx7 = getelementptr inbounds nuw i8, ptr %p, i32 28 |
| store i32 %v, ptr %idx7, align 1 |
| ret void |
| } |
| |
| ; Negative test sections, non-128 bit versions not vectorize. |
| |
| define void @splat_i32x2(i32 %v, ptr noalias %p) { |
| ; SIMD128-LABEL: @splat_i32x2( |
| ; SIMD128-NEXT: entry: |
| ; SIMD128-NEXT: store i32 [[V:%.*]], ptr [[P:%.*]], align 1 |
| ; SIMD128-NEXT: [[IDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 4 |
| ; SIMD128-NEXT: store i32 [[V]], ptr [[IDX1]], align 1 |
| ; SIMD128-NEXT: ret void |
| ; |
| ; NO-SIMD128-LABEL: @splat_i32x2( |
| ; NO-SIMD128-NEXT: entry: |
| ; NO-SIMD128-NEXT: store i32 [[V:%.*]], ptr [[P:%.*]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 4 |
| ; NO-SIMD128-NEXT: store i32 [[V]], ptr [[IDX1]], align 1 |
| ; NO-SIMD128-NEXT: ret void |
| ; |
| entry: |
| store i32 %v, ptr %p, align 1 |
| %idx1 = getelementptr inbounds nuw i8, ptr %p, i32 4 |
| store i32 %v, ptr %idx1, align 1 |
| ret void |
| } |
| |
| define void @splat_i16x4(i16 %v, ptr noalias %p) { |
| ; SIMD128-LABEL: @splat_i16x4( |
| ; SIMD128-NEXT: entry: |
| ; SIMD128-NEXT: store i16 [[V:%.*]], ptr [[P:%.*]], align 1 |
| ; SIMD128-NEXT: [[IDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 2 |
| ; SIMD128-NEXT: store i16 [[V]], ptr [[IDX1]], align 1 |
| ; SIMD128-NEXT: [[IDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 4 |
| ; SIMD128-NEXT: store i16 [[V]], ptr [[IDX2]], align 1 |
| ; SIMD128-NEXT: [[IDX3:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 6 |
| ; SIMD128-NEXT: store i16 [[V]], ptr [[IDX3]], align 1 |
| ; SIMD128-NEXT: ret void |
| ; |
| ; NO-SIMD128-LABEL: @splat_i16x4( |
| ; NO-SIMD128-NEXT: entry: |
| ; NO-SIMD128-NEXT: store i16 [[V:%.*]], ptr [[P:%.*]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 2 |
| ; NO-SIMD128-NEXT: store i16 [[V]], ptr [[IDX1]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 4 |
| ; NO-SIMD128-NEXT: store i16 [[V]], ptr [[IDX2]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX3:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 6 |
| ; NO-SIMD128-NEXT: store i16 [[V]], ptr [[IDX3]], align 1 |
| ; NO-SIMD128-NEXT: ret void |
| ; |
| entry: |
| store i16 %v, ptr %p, align 1 |
| %idx1 = getelementptr inbounds nuw i8, ptr %p, i32 2 |
| store i16 %v, ptr %idx1, align 1 |
| %idx2 = getelementptr inbounds nuw i8, ptr %p, i32 4 |
| store i16 %v, ptr %idx2, align 1 |
| %idx3 = getelementptr inbounds nuw i8, ptr %p, i32 6 |
| store i16 %v, ptr %idx3, align 1 |
| ret void |
| } |
| |
| define void @splat_i8x8(i8 %v, ptr noalias %p) { |
| ; SIMD128-LABEL: @splat_i8x8( |
| ; SIMD128-NEXT: entry: |
| ; SIMD128-NEXT: store i8 [[V:%.*]], ptr [[P:%.*]], align 1 |
| ; SIMD128-NEXT: [[IDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 1 |
| ; SIMD128-NEXT: store i8 [[V]], ptr [[IDX1]], align 1 |
| ; SIMD128-NEXT: [[IDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 2 |
| ; SIMD128-NEXT: store i8 [[V]], ptr [[IDX2]], align 1 |
| ; SIMD128-NEXT: [[IDX3:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 3 |
| ; SIMD128-NEXT: store i8 [[V]], ptr [[IDX3]], align 1 |
| ; SIMD128-NEXT: [[IDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 4 |
| ; SIMD128-NEXT: store i8 [[V]], ptr [[IDX4]], align 1 |
| ; SIMD128-NEXT: [[IDX5:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 5 |
| ; SIMD128-NEXT: store i8 [[V]], ptr [[IDX5]], align 1 |
| ; SIMD128-NEXT: [[IDX6:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 6 |
| ; SIMD128-NEXT: store i8 [[V]], ptr [[IDX6]], align 1 |
| ; SIMD128-NEXT: [[IDX7:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 7 |
| ; SIMD128-NEXT: store i8 [[V]], ptr [[IDX7]], align 1 |
| ; SIMD128-NEXT: ret void |
| ; |
| ; NO-SIMD128-LABEL: @splat_i8x8( |
| ; NO-SIMD128-NEXT: entry: |
| ; NO-SIMD128-NEXT: store i8 [[V:%.*]], ptr [[P:%.*]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 1 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX1]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 2 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX2]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX3:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 3 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX3]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 4 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX4]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX5:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 5 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX5]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX6:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 6 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX6]], align 1 |
| ; NO-SIMD128-NEXT: [[IDX7:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i32 7 |
| ; NO-SIMD128-NEXT: store i8 [[V]], ptr [[IDX7]], align 1 |
| ; NO-SIMD128-NEXT: ret void |
| ; |
| entry: |
| store i8 %v, ptr %p, align 1 |
| %idx1 = getelementptr inbounds nuw i8, ptr %p, i32 1 |
| store i8 %v, ptr %idx1, align 1 |
| %idx2 = getelementptr inbounds nuw i8, ptr %p, i32 2 |
| store i8 %v, ptr %idx2, align 1 |
| %idx3 = getelementptr inbounds nuw i8, ptr %p, i32 3 |
| store i8 %v, ptr %idx3, align 1 |
| %idx4 = getelementptr inbounds nuw i8, ptr %p, i32 4 |
| store i8 %v, ptr %idx4, align 1 |
| %idx5 = getelementptr inbounds nuw i8, ptr %p, i32 5 |
| store i8 %v, ptr %idx5, align 1 |
| %idx6 = getelementptr inbounds nuw i8, ptr %p, i32 6 |
| store i8 %v, ptr %idx6, align 1 |
| %idx7 = getelementptr inbounds nuw i8, ptr %p, i32 7 |
| store i8 %v, ptr %idx7, align 1 |
| ret void |
| } |
| |