diff --git a/llvm/include/llvm/IR/IntrinsicsVE.td b/llvm/include/llvm/IR/IntrinsicsVE.td --- a/llvm/include/llvm/IR/IntrinsicsVE.td +++ b/llvm/include/llvm/IR/IntrinsicsVE.td @@ -4,6 +4,13 @@ let TargetPrefix = "ve" in { def int_ve_vl_svob : GCCBuiltin<"__builtin_ve_vl_svob">, Intrinsic<[], [], [IntrHasSideEffects]>; + + def int_ve_vl_pack_f32p : GCCBuiltin<"__builtin_ve_vl_pack_f32p">, + Intrinsic<[llvm_i64_ty], [llvm_ptr_ty, llvm_ptr_ty], + [IntrReadMem]>; + def int_ve_vl_pack_f32a : GCCBuiltin<"__builtin_ve_vl_pack_f32a">, + Intrinsic<[llvm_i64_ty], [llvm_ptr_ty], + [IntrReadMem]>; } // Define intrinsics automatically generated diff --git a/llvm/lib/Target/VE/VEInstrIntrinsicVL.td b/llvm/lib/Target/VE/VEInstrIntrinsicVL.td --- a/llvm/lib/Target/VE/VEInstrIntrinsicVL.td +++ b/llvm/lib/Target/VE/VEInstrIntrinsicVL.td @@ -5,6 +5,18 @@ // SVOB pattern. def : Pat<(int_ve_vl_svob), (SVOB)>; +// Pack patterns. +def : Pat<(i64 (int_ve_vl_pack_f32p ADDRrii:$addr0, ADDRrii:$addr1)), + (ORrr (f2l (LDUrii MEMrii:$addr0)), + (i2l (LDLZXrii MEMrii:$addr1)))>; + +def : Pat<(i64 (int_ve_vl_pack_f32a ADDRrii:$addr)), + (MULULrr + (i2l (LDLZXrii MEMrii:$addr)), + (LEASLrii (ANDrm (LEAzii 0, 0, (LO32 (i64 0x0000000100000001))), + !add(32, 64)), 0, + (HI32 (i64 0x0000000100000001))))>; + // LSV patterns. def : Pat<(int_ve_vl_lsv_vvss v256f64:$pt, i32:$sy, i64:$sz), (LSVrr_v (i2l i32:$sy), i64:$sz, v256f64:$pt)>; diff --git a/llvm/test/CodeGen/VE/VELIntrinsics/pack.ll b/llvm/test/CodeGen/VE/VELIntrinsics/pack.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/VE/VELIntrinsics/pack.ll @@ -0,0 +1,41 @@ +; RUN: llc < %s -mtriple=ve -mattr=+vpu | FileCheck %s + +;;; Test pack intrinsic instructions +;;; +;;; Note: +;;; We test pack_f32p and pack_f32a pseudo instruction. + +; Function Attrs: nounwind readonly +define fastcc i64 @pack_f32p(float* readonly %0, float* readonly %1) { +; CHECK-LABEL: pack_f32p: +; CHECK: # %bb.0: +; CHECK-NEXT: ldu %s0, (, %s0) +; CHECK-NEXT: ldl.zx %s1, (, %s1) +; CHECK-NEXT: or %s0, %s0, %s1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = bitcast float* %0 to i8* + %4 = bitcast float* %1 to i8* + %5 = tail call i64 @llvm.ve.vl.pack.f32p(i8* %3, i8* %4) + ret i64 %5 +} + +; Function Attrs: nounwind readonly +declare i64 @llvm.ve.vl.pack.f32p(i8*, i8*) + +; Function Attrs: nounwind readonly +define fastcc i64 @pack_f32a(float* readonly %0) { +; CHECK-LABEL: pack_f32a: +; CHECK: # %bb.0: +; CHECK-NEXT: ldl.zx %s0, (, %s0) +; CHECK-NEXT: lea %s1, 1 +; CHECK-NEXT: and %s1, %s1, (32)0 +; CHECK-NEXT: lea.sl %s1, 1(, %s1) +; CHECK-NEXT: mulu.l %s0, %s0, %s1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = bitcast float* %0 to i8* + %3 = tail call i64 @llvm.ve.vl.pack.f32a(i8* %2) + ret i64 %3 +} + +; Function Attrs: nounwind readonly +declare i64 @llvm.ve.vl.pack.f32a(i8*)