179 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s3 4; Test optimization of DUP with extended narrow loads5; This should avoid GPR->SIMD transfers by loading directly into vector registers6 7define <4 x i16> @test_dup_zextload_i8_v4i16(ptr %p) {8; CHECK-LABEL: test_dup_zextload_i8_v4i16:9; CHECK: // %bb.0:10; CHECK-NEXT: ldr b0, [x0]11; CHECK-NEXT: dup v0.4h, v0.h[0]12; CHECK-NEXT: ret13 %load = load i8, ptr %p, align 114 %ext = zext i8 %load to i1615 %vec = insertelement <4 x i16> poison, i16 %ext, i32 016 %dup = shufflevector <4 x i16> %vec, <4 x i16> poison, <4 x i32> zeroinitializer17 ret <4 x i16> %dup18}19 20define <8 x i16> @test_dup_zextload_i8_v8i16(ptr %p) {21; CHECK-LABEL: test_dup_zextload_i8_v8i16:22; CHECK: // %bb.0:23; CHECK-NEXT: ldr b0, [x0]24; CHECK-NEXT: dup v0.8h, v0.h[0]25; CHECK-NEXT: ret26 %load = load i8, ptr %p, align 127 %ext = zext i8 %load to i1628 %vec = insertelement <8 x i16> poison, i16 %ext, i32 029 %dup = shufflevector <8 x i16> %vec, <8 x i16> poison, <8 x i32> zeroinitializer30 ret <8 x i16> %dup31}32 33define <2 x i32> @test_dup_zextload_i8_v2i32(ptr %p) {34; CHECK-LABEL: test_dup_zextload_i8_v2i32:35; CHECK: // %bb.0:36; CHECK-NEXT: ldr b0, [x0]37; CHECK-NEXT: dup v0.2s, v0.s[0]38; CHECK-NEXT: ret39 %load = load i8, ptr %p, align 140 %ext = zext i8 %load to i3241 %vec = insertelement <2 x i32> poison, i32 %ext, i32 042 %dup = shufflevector <2 x i32> %vec, <2 x i32> poison, <2 x i32> zeroinitializer43 ret <2 x i32> %dup44}45 46define <4 x i32> @test_dup_zextload_i8_v4i32(ptr %p) {47; CHECK-LABEL: test_dup_zextload_i8_v4i32:48; CHECK: // %bb.0:49; CHECK-NEXT: ldr b0, [x0]50; CHECK-NEXT: dup v0.4s, v0.s[0]51; CHECK-NEXT: ret52 %load = load i8, ptr %p, align 153 %ext = zext i8 %load to i3254 %vec = insertelement <4 x i32> poison, i32 %ext, i32 055 %dup = shufflevector <4 x i32> %vec, <4 x i32> poison, <4 x i32> zeroinitializer56 ret <4 x i32> %dup57}58 59define <4 x i32> @test_dup_zextload_i8_v4i32_offset(ptr %p) {60; CHECK-LABEL: test_dup_zextload_i8_v4i32_offset:61; CHECK: // %bb.0:62; CHECK-NEXT: ldr b0, [x0, #4]63; CHECK-NEXT: dup v0.4s, v0.s[0]64; CHECK-NEXT: ret65 %addr = getelementptr inbounds i8, ptr %p, i64 466 %load = load i8, ptr %addr, align 167 %ext = zext i8 %load to i3268 %vec = insertelement <4 x i32> poison, i32 %ext, i32 069 %dup = shufflevector <4 x i32> %vec, <4 x i32> poison, <4 x i32> zeroinitializer70 ret <4 x i32> %dup71}72 73define <4 x i32> @test_dup_zextload_i8_v4i32_reg_offset(ptr %p, i64 %offset) {74; CHECK-LABEL: test_dup_zextload_i8_v4i32_reg_offset:75; CHECK: // %bb.0:76; CHECK-NEXT: ldr b0, [x0, x1]77; CHECK-NEXT: dup v0.4s, v0.s[0]78; CHECK-NEXT: ret79 %addr = getelementptr inbounds i8, ptr %p, i64 %offset80 %load = load i8, ptr %addr, align 181 %ext = zext i8 %load to i3282 %vec = insertelement <4 x i32> poison, i32 %ext, i32 083 %dup = shufflevector <4 x i32> %vec, <4 x i32> poison, <4 x i32> zeroinitializer84 ret <4 x i32> %dup85}86 87define <2 x i64> @test_dup_zextload_i8_v2i64(ptr %p) {88; CHECK-LABEL: test_dup_zextload_i8_v2i64:89; CHECK: // %bb.0:90; CHECK-NEXT: ldr b0, [x0]91; CHECK-NEXT: dup v0.2d, v0.d[0]92; CHECK-NEXT: ret93 %load = load i8, ptr %p, align 194 %ext = zext i8 %load to i6495 %vec = insertelement <2 x i64> poison, i64 %ext, i32 096 %dup = shufflevector <2 x i64> %vec, <2 x i64> poison, <2 x i32> zeroinitializer97 ret <2 x i64> %dup98}99 100define <2 x i32> @test_dup_zextload_i16_v2i32(ptr %p) {101; CHECK-LABEL: test_dup_zextload_i16_v2i32:102; CHECK: // %bb.0:103; CHECK-NEXT: ldr h0, [x0]104; CHECK-NEXT: dup v0.2s, v0.s[0]105; CHECK-NEXT: ret106 %load = load i16, ptr %p, align 1107 %ext = zext i16 %load to i32108 %vec = insertelement <2 x i32> poison, i32 %ext, i32 0109 %dup = shufflevector <2 x i32> %vec, <2 x i32> poison, <2 x i32> zeroinitializer110 ret <2 x i32> %dup111}112 113define <4 x i32> @test_dup_zextload_i16_v4i32(ptr %p) {114; CHECK-LABEL: test_dup_zextload_i16_v4i32:115; CHECK: // %bb.0:116; CHECK-NEXT: ldr h0, [x0]117; CHECK-NEXT: dup v0.4s, v0.s[0]118; CHECK-NEXT: ret119 %load = load i16, ptr %p, align 1120 %ext = zext i16 %load to i32121 %vec = insertelement <4 x i32> poison, i32 %ext, i32 0122 %dup = shufflevector <4 x i32> %vec, <4 x i32> poison, <4 x i32> zeroinitializer123 ret <4 x i32> %dup124}125 126define <4 x i32> @test_dup_zextload_i16_v4i32_offset(ptr %p) {127; CHECK-LABEL: test_dup_zextload_i16_v4i32_offset:128; CHECK: // %bb.0:129; CHECK-NEXT: ldr h0, [x0, #8]130; CHECK-NEXT: dup v0.4s, v0.s[0]131; CHECK-NEXT: ret132 %addr = getelementptr inbounds i16, ptr %p, i64 4133 %load = load i16, ptr %addr, align 1134 %ext = zext i16 %load to i32135 %vec = insertelement <4 x i32> poison, i32 %ext, i32 0136 %dup = shufflevector <4 x i32> %vec, <4 x i32> poison, <4 x i32> zeroinitializer137 ret <4 x i32> %dup138}139 140define <4 x i32> @test_dup_zextload_i16_v4i32_reg_offset(ptr %p, i64 %offset) {141; CHECK-LABEL: test_dup_zextload_i16_v4i32_reg_offset:142; CHECK: // %bb.0:143; CHECK-NEXT: ldr h0, [x0, x1, lsl #1]144; CHECK-NEXT: dup v0.4s, v0.s[0]145; CHECK-NEXT: ret146 %addr = getelementptr inbounds i16, ptr %p, i64 %offset147 %load = load i16, ptr %addr, align 1148 %ext = zext i16 %load to i32149 %vec = insertelement <4 x i32> poison, i32 %ext, i32 0150 %dup = shufflevector <4 x i32> %vec, <4 x i32> poison, <4 x i32> zeroinitializer151 ret <4 x i32> %dup152}153 154define <2 x i64> @test_dup_zextload_i16_v2i64(ptr %p) {155; CHECK-LABEL: test_dup_zextload_i16_v2i64:156; CHECK: // %bb.0:157; CHECK-NEXT: ldr h0, [x0]158; CHECK-NEXT: dup v0.2d, v0.d[0]159; CHECK-NEXT: ret160 %load = load i16, ptr %p, align 1161 %ext = zext i16 %load to i64162 %vec = insertelement <2 x i64> poison, i64 %ext, i32 0163 %dup = shufflevector <2 x i64> %vec, <2 x i64> poison, <2 x i32> zeroinitializer164 ret <2 x i64> %dup165}166 167define <2 x i64> @test_dup_zextload_i32_v2i64(ptr %p) {168; CHECK-LABEL: test_dup_zextload_i32_v2i64:169; CHECK: // %bb.0:170; CHECK-NEXT: ldr s0, [x0]171; CHECK-NEXT: dup v0.2d, v0.d[0]172; CHECK-NEXT: ret173 %load = load i32, ptr %p, align 1174 %ext = zext i32 %load to i64175 %vec = insertelement <2 x i64> poison, i64 %ext, i32 0176 %dup = shufflevector <2 x i64> %vec, <2 x i64> poison, <2 x i32> zeroinitializer177 ret <2 x i64> %dup178}179