diff options
author | Kit Barton <kbarton@ca.ibm.com> | 2015-05-25 15:49:26 +0000 |
---|---|---|
committer | Kit Barton <kbarton@ca.ibm.com> | 2015-05-25 15:49:26 +0000 |
commit | 6646033e6e759657b6122fde64844fd28a2c9635 (patch) | |
tree | b29623a45a12224714ae003592cb553300c8a875 /llvm/test/CodeGen | |
parent | b028cc80989ccbdeb6940d89b1bac5a036377249 (diff) | |
download | bcm5719-llvm-6646033e6e759657b6122fde64844fd28a2c9635.tar.gz bcm5719-llvm-6646033e6e759657b6122fde64844fd28a2c9635.zip |
This patch adds support for the vector quadword add/sub instructions introduced
in POWER8:
vadduqm
vaddeuqm
vaddcuq
vaddecuq
vsubuqm
vsubeuqm
vsubcuq
vsubecuq
In addition to adding the instructions themselves, it also adds support for the
v1i128 type for intrinsics (Intrinsics.td, Function.cpp, and
IntrinsicEmitter.cpp).
http://reviews.llvm.org/D9081
llvm-svn: 238144
Diffstat (limited to 'llvm/test/CodeGen')
-rw-r--r-- | llvm/test/CodeGen/PowerPC/ppc64-i128-abi.ll | 50 | ||||
-rw-r--r-- | llvm/test/CodeGen/PowerPC/vec_add_sub_quadword.ll | 130 |
2 files changed, 150 insertions, 30 deletions
diff --git a/llvm/test/CodeGen/PowerPC/ppc64-i128-abi.ll b/llvm/test/CodeGen/PowerPC/ppc64-i128-abi.ll index 8a8824d0184..993aec24c8f 100644 --- a/llvm/test/CodeGen/PowerPC/ppc64-i128-abi.ll +++ b/llvm/test/CodeGen/PowerPC/ppc64-i128-abi.ll @@ -12,46 +12,46 @@ ; VSX: ; %a is passed in register 34 -; On LE, ensure %a is swapped before being used (using xxswapd) -; Similarly, on LE ensure the results are swapped before being returned in -; register 34 +; The value of 1 is stored in the TOC. +; On LE, ensure the value of 1 is swapped before being used (using xxswapd). ; VMX (no VSX): ; %a is passed in register 2 -; No swaps are necessary on LE +; The value of 1 is stored in the TOC. +; No swaps are necessary when using P8 Vector instructions on LE define <1 x i128> @v1i128_increment_by_one(<1 x i128> %a) nounwind { %tmp = add <1 x i128> %a, <i128 1> ret <1 x i128> %tmp +; FIXME: Seems a 128-bit literal is materialized by loading from the TOC. There +; should be a better way of doing this. + ; CHECK-LE-LABEL: @v1i128_increment_by_one -; CHECK-LE: xxswapd [[PARAM1:[0-9]+]], 34 -; CHECK-LE: stxvd2x [[PARAM1]], {{[0-9]+}}, {{[0-9]+}} -; CHECK-LE: lxvd2x [[RESULT:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} -; CHECK-LE: xxswapd 34, [[RESULT]] +; CHECK-LE: lxvd2x [[VAL:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} +; CHECK-LE: xxswapd 35, [[VAL]] +; CHECK-LE: vadduqm 2, 2, 3 ; CHECK-LE: blr ; CHECK-BE-LABEL: @v1i128_increment_by_one -; CHECK-BE-NOT: xxswapd {{[0-9]+}}, 34 -; CHECK-BE: stxvd2x 34, {{[0-9]+}}, {{[0-9]+}} -; CHECK-BE: lxvd2x 34, {{[0-9]+}}, {{[0-9]+}} +; CHECK-BE: lxvd2x 35, {{[0-9]+}}, {{[0-9]+}} +; CHECK-BE-NOT: xxswapd +; CHECK-BE: vadduqm 2, 2, 3 ; CHECK-BE-NOT: xxswapd 34, {{[0-9]+}} ; CHECK-BE: blr ; CHECK-NOVSX-LABEL: @v1i128_increment_by_one ; CHECK-NOVSX-NOT: xxswapd {{[0-9]+}}, {{[0-9]+}} ; CHECK-NOVSX-NOT: stxvd2x {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} -; CHECK-NOVSX: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK-NOVSX: lvx 2, {{[0-9]+}}, {{[0-9]+}} +; CHECK-NOVSX: lvx [[VAL:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK-NOVSX-NOT: lxvd2x {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}} ; CHECK-NOVSX-NOT: xxswapd {{[0-9]+}}, {{[0-9]+}} +; CHECK-NOVSX: vadduqm 2, 2, [[VAL]] ; CHECK-NOVSX: blr } ; VSX: ; %a is passed in register 34 ; %b is passed in register 35 -; On LE, ensure the contents of 34 and 35 are swapped before being used -; Similarly, on LE ensure the results are swapped before being returned in -; register 34 +; No swaps are necessary when using P8 Vector instructions on LE ; VMX (no VSX): ; %a is passewd in register 2 ; %b is passed in register 3 @@ -62,30 +62,20 @@ define <1 x i128> @v1i128_increment_by_val(<1 x i128> %a, <1 x i128> %b) nounwin ret <1 x i128> %tmp ; CHECK-LE-LABEL: @v1i128_increment_by_val -; CHECK-LE-DAG: xxswapd [[PARAM1:[0-9]+]], 34 -; CHECK-LE-DAG: xxswapd [[PARAM2:[0-9]+]], 35 -; CHECK-LE-DAG: stxvd2x [[PARAM1]], {{[0-9]+}}, {{[0-9]+}} -; CHECK-LE-DAG: stxvd2x [[PARAM2]], {{[0-9]+}}, {{[0-9]+}} -; CHECK-LE: lxvd2x [[RESULT:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} -; CHECK-LE: xxswapd 34, [[RESULT]] +; CHECK-LE-NOT: xxswapd +; CHECK-LE: adduqm 2, 2, 3 ; CHECK-LE: blr ; CHECK-BE-LABEL: @v1i128_increment_by_val ; CHECK-BE-NOT: xxswapd {{[0-9]+}}, 34 ; CHECK-BE-NOT: xxswapd {{[0-9]+}}, 35 -; CHECK-BE-DAG: stxvd2x 34, {{[0-9]+}}, {{[0-9]+}} -; CHECK-BE-DAG: stxvd2x 35, {{[0-9]+}}, {{[0-9]+}} -; CHECK-BE: lxvd2x [[RESULT:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK-BE-NOT: xxswapd 34, [[RESULT]] +; CHECK-BE: adduqm 2, 2, 3 ; CHECK-BE: blr ; CHECK-NOVSX-LABEL: @v1i128_increment_by_val -; CHECK-NOVSX-NOT: xxswapd {{[0-9]+}}, {{[0-9]+}} -; CHECK-NOVSX-NOT: xxswapd {{[0-9]+}}, {{[0-9]+}} -; CHECK-NOVSX-DAG: stvx 2, {{[0-9]+}}, {{[0-9]+}} -; CHECK-NOVSX-DAG: stvx 3, {{[0-9]+}}, {{[0-9]+}} -; CHECK-NOVSX: lvx [[RESULT:[0-9]+]], {{[0-9]+}}, {{[0-9]+}} ; CHECK-NOVSX-NOT: xxswapd 34, [[RESULT]] +; CHECK-NOVSX: adduqm 2, 2, 3 ; CHECK-NOVSX: blr } diff --git a/llvm/test/CodeGen/PowerPC/vec_add_sub_quadword.ll b/llvm/test/CodeGen/PowerPC/vec_add_sub_quadword.ll new file mode 100644 index 00000000000..f7ebf479755 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/vec_add_sub_quadword.ll @@ -0,0 +1,130 @@ +; Check VMX 128-bit integer operations +; +; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 < %s | FileCheck %s +; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 -mattr=-vsx < %s | FileCheck %s + +define <1 x i128> @test_add(<1 x i128> %x, <1 x i128> %y) nounwind { + %result = add <1 x i128> %x, %y + ret <1 x i128> %result +; CHECK-LABEL: @test_add +; CHECK: vadduqm 2, 2, 3 +} + +define <1 x i128> @increment_by_one(<1 x i128> %x) nounwind { + %result = add <1 x i128> %x, <i128 1> + ret <1 x i128> %result +; CHECK-LABEL: @increment_by_one +; CHECK vadduqm 2, 2, 3 +} + +define <1 x i128> @increment_by_val(<1 x i128> %x, i128 %val) nounwind { + %tmpvec = insertelement <1 x i128> <i128 0>, i128 %val, i32 0 + %tmpvec2 = insertelement <1 x i128> %tmpvec, i128 %val, i32 1 + %result = add <1 x i128> %x, %tmpvec2 + ret <1 x i128> %result +; CHECK-LABEL: @increment_by_val +; CHECK: vadduqm 2, 2, 3 +} + +define <1 x i128> @test_sub(<1 x i128> %x, <1 x i128> %y) nounwind { + %result = sub <1 x i128> %x, %y + ret <1 x i128> %result +; CHECK-LABEL: @test_sub +; CHECK: vsubuqm 2, 2, 3 +} + +define <1 x i128> @decrement_by_one(<1 x i128> %x) nounwind { + %result = sub <1 x i128> %x, <i128 1> + ret <1 x i128> %result +; CHECK-LABEL: @decrement_by_one +; CHECK vsubuqm 2, 2, 3 +} + +define <1 x i128> @decrement_by_val(<1 x i128> %x, i128 %val) nounwind { + %tmpvec = insertelement <1 x i128> <i128 0>, i128 %val, i32 0 + %tmpvec2 = insertelement <1 x i128> %tmpvec, i128 %val, i32 1 + %result = sub <1 x i128> %x, %tmpvec2 + ret <1 x i128> %result +; CHECK-LABEL: @decrement_by_val +; CHECK vsubuqm 2, 2, 3 +} + +declare <1 x i128> @llvm.ppc.altivec.vaddeuqm(<1 x i128> %x, + <1 x i128> %y, + <1 x i128> %z) nounwind readnone +declare <1 x i128> @llvm.ppc.altivec.vaddcuq(<1 x i128> %x, + <1 x i128> %y) nounwind readnone +declare <1 x i128> @llvm.ppc.altivec.vaddecuq(<1 x i128> %x, + <1 x i128> %y, + <1 x i128> %z) nounwind readnone +declare <1 x i128> @llvm.ppc.altivec.vsubeuqm(<1 x i128> %x, + <1 x i128> %y, + <1 x i128> %z) nounwind readnone +declare <1 x i128> @llvm.ppc.altivec.vsubcuq(<1 x i128> %x, + <1 x i128> %y) nounwind readnone +declare <1 x i128> @llvm.ppc.altivec.vsubecuq(<1 x i128> %x, + <1 x i128> %y, + <1 x i128> %z) nounwind readnone + +define <1 x i128> @test_vaddeuqm(<1 x i128> %x, + <1 x i128> %y, + <1 x i128> %z) nounwind { + %tmp = tail call <1 x i128> @llvm.ppc.altivec.vaddeuqm(<1 x i128> %x, + <1 x i128> %y, + <1 x i128> %z) + ret <1 x i128> %tmp +; CHECK-LABEL: @test_vaddeuqm +; CHECK: vaddeuqm 2, 2, 3, 4 +} + +define <1 x i128> @test_vaddcuq(<1 x i128> %x, + <1 x i128> %y) nounwind { + %tmp = tail call <1 x i128> @llvm.ppc.altivec.vaddcuq(<1 x i128> %x, + <1 x i128> %y) + ret <1 x i128> %tmp +; CHECK-LABEL: @test_vaddcuq +; CHECK: vaddcuq 2, 2, 3 +} + +define <1 x i128> @test_vaddecuq(<1 x i128> %x, + <1 x i128> %y, + <1 x i128> %z) nounwind { + %tmp = tail call <1 x i128> @llvm.ppc.altivec.vaddecuq(<1 x i128> %x, + <1 x i128> %y, + <1 x i128> %z) + ret <1 x i128> %tmp +; CHECK-LABEL: @test_vaddecuq +; CHECK: vaddecuq 2, 2, 3, 4 +} + +define <1 x i128> @test_vsubeuqm(<1 x i128> %x, + <1 x i128> %y, + <1 x i128> %z) nounwind { + %tmp = tail call <1 x i128> @llvm.ppc.altivec.vsubeuqm(<1 x i128> %x, + <1 x i128> %y, + <1 x i128> %z) + ret <1 x i128> %tmp +; CHECK-LABEL: test_vsubeuqm +; CHECK: vsubeuqm 2, 2, 3, 4 +} + +define <1 x i128> @test_vsubcuq(<1 x i128> %x, + <1 x i128> %y) nounwind { + %tmp = tail call <1 x i128> @llvm.ppc.altivec.vsubcuq(<1 x i128> %x, + <1 x i128> %y) + ret <1 x i128> %tmp +; CHECK-LABEL: test_vsubcuq +; CHECK: vsubcuq 2, 2, 3 +} + +define <1 x i128> @test_vsubecuq(<1 x i128> %x, + <1 x i128> %y, + <1 x i128> %z) nounwind { + %tmp = tail call <1 x i128> @llvm.ppc.altivec.vsubecuq(<1 x i128> %x, + <1 x i128> %y, + <1 x i128> %z) + ret <1 x i128> %tmp +; CHECK-LABEL: test_vsubecuq +; CHECK: vsubecuq 2, 2, 3, 4 +} + |