1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mcpu=pwr6 -mattr=+altivec -code-model=small < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; Check vector extend load expansion with altivec enabled. 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Workertarget datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64" 6*9880d681SAndroid Build Coastguard Workertarget triple = "powerpc64-unknown-linux-gnu" 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Worker; Altivec does not provides an sext instruction, so it expands 9*9880d681SAndroid Build Coastguard Worker; a set of vector stores (stvx), bytes load/sign expand/store 10*9880d681SAndroid Build Coastguard Worker; (lbz/stb), and a final vector load (lvx) to load the result 11*9880d681SAndroid Build Coastguard Worker; extended vector. 12*9880d681SAndroid Build Coastguard Workerdefine <16 x i8> @v16si8_sext_in_reg(<16 x i8> %a) { 13*9880d681SAndroid Build Coastguard Worker %b = trunc <16 x i8> %a to <16 x i4> 14*9880d681SAndroid Build Coastguard Worker %c = sext <16 x i4> %b to <16 x i8> 15*9880d681SAndroid Build Coastguard Worker ret <16 x i8> %c 16*9880d681SAndroid Build Coastguard Worker} 17*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: v16si8_sext_in_reg: 18*9880d681SAndroid Build Coastguard Worker; CHECK: vslb 19*9880d681SAndroid Build Coastguard Worker; CHECK: vsrab 20*9880d681SAndroid Build Coastguard Worker; CHECK: blr 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Worker; The zero extend uses a more clever logic: a vector splat 23*9880d681SAndroid Build Coastguard Worker; and a logic and to set higher bits to 0. 24*9880d681SAndroid Build Coastguard Workerdefine <16 x i8> @v16si8_zext_in_reg(<16 x i8> %a) { 25*9880d681SAndroid Build Coastguard Worker %b = trunc <16 x i8> %a to <16 x i4> 26*9880d681SAndroid Build Coastguard Worker %c = zext <16 x i4> %b to <16 x i8> 27*9880d681SAndroid Build Coastguard Worker ret <16 x i8> %c 28*9880d681SAndroid Build Coastguard Worker} 29*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: v16si8_zext_in_reg: 30*9880d681SAndroid Build Coastguard Worker; CHECK: vspltisb [[VMASK:[0-9]+]], 15 31*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: vand 2, 2, [[VMASK]] 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Worker; Same as v16si8_sext_in_reg, expands to load/store halfwords (lhz/sth). 34*9880d681SAndroid Build Coastguard Workerdefine <8 x i16> @v8si16_sext_in_reg(<8 x i16> %a) { 35*9880d681SAndroid Build Coastguard Worker %b = trunc <8 x i16> %a to <8 x i8> 36*9880d681SAndroid Build Coastguard Worker %c = sext <8 x i8> %b to <8 x i16> 37*9880d681SAndroid Build Coastguard Worker ret <8 x i16> %c 38*9880d681SAndroid Build Coastguard Worker} 39*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: v8si16_sext_in_reg: 40*9880d681SAndroid Build Coastguard Worker; CHECK: vslh 41*9880d681SAndroid Build Coastguard Worker; CHECK: vsrah 42*9880d681SAndroid Build Coastguard Worker; CHECK: blr 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Worker; Same as v8si16_sext_in_reg, but instead of creating the mask 45*9880d681SAndroid Build Coastguard Worker; with a splat, loads it from memory. 46*9880d681SAndroid Build Coastguard Workerdefine <8 x i16> @v8si16_zext_in_reg(<8 x i16> %a) { 47*9880d681SAndroid Build Coastguard Worker %b = trunc <8 x i16> %a to <8 x i8> 48*9880d681SAndroid Build Coastguard Worker %c = zext <8 x i8> %b to <8 x i16> 49*9880d681SAndroid Build Coastguard Worker ret <8 x i16> %c 50*9880d681SAndroid Build Coastguard Worker} 51*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: v8si16_zext_in_reg: 52*9880d681SAndroid Build Coastguard Worker; CHECK: ld [[RMASKTOC:[0-9]+]], .LC{{[0-9]+}}@toc(2) 53*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lvx [[VMASK:[0-9]+]], {{[0-9]+}}, [[RMASKTOC]] 54*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: vand 2, 2, [[VMASK]] 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Worker; Same as v16si8_sext_in_reg, expands to load halfword (lha) and 57*9880d681SAndroid Build Coastguard Worker; store words (stw). 58*9880d681SAndroid Build Coastguard Workerdefine <4 x i32> @v4si32_sext_in_reg(<4 x i32> %a) { 59*9880d681SAndroid Build Coastguard Worker %b = trunc <4 x i32> %a to <4 x i16> 60*9880d681SAndroid Build Coastguard Worker %c = sext <4 x i16> %b to <4 x i32> 61*9880d681SAndroid Build Coastguard Worker ret <4 x i32> %c 62*9880d681SAndroid Build Coastguard Worker} 63*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: v4si32_sext_in_reg: 64*9880d681SAndroid Build Coastguard Worker; CHECK: vslw 65*9880d681SAndroid Build Coastguard Worker; CHECK: vsraw 66*9880d681SAndroid Build Coastguard Worker; CHECK: blr 67*9880d681SAndroid Build Coastguard Worker 68*9880d681SAndroid Build Coastguard Worker; Same as v8si16_sext_in_reg. 69*9880d681SAndroid Build Coastguard Workerdefine <4 x i32> @v4si32_zext_in_reg(<4 x i32> %a) { 70*9880d681SAndroid Build Coastguard Worker %b = trunc <4 x i32> %a to <4 x i16> 71*9880d681SAndroid Build Coastguard Worker %c = zext <4 x i16> %b to <4 x i32> 72*9880d681SAndroid Build Coastguard Worker ret <4 x i32> %c 73*9880d681SAndroid Build Coastguard Worker} 74*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: v4si32_zext_in_reg: 75*9880d681SAndroid Build Coastguard Worker; CHECK: vspltisw [[VMASK:[0-9]+]], -16 76*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: vsrw [[VMASK]], [[VMASK]], [[VMASK]] 77*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: vand 2, 2, [[VMASK]] 78