diff --git a/llvm/lib/Target/VE/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp --- a/llvm/lib/Target/VE/VEISelLowering.cpp +++ b/llvm/lib/Target/VE/VEISelLowering.cpp @@ -501,6 +501,12 @@ MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0)); setOperationAction(ISD::GlobalAddress, PtrVT, Custom); + // VE doesn't have instructions for fp<->uint, so expand them by llvm + setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote); // use i64 + setOperationAction(ISD::UINT_TO_FP, MVT::i32, Promote); // use i64 + setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand); + setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand); + setStackPointerRegisterToSaveRestore(VE::SX11); // Set function alignment to 16 bytes diff --git a/llvm/lib/Target/VE/VEInstrInfo.td b/llvm/lib/Target/VE/VEInstrInfo.td --- a/llvm/lib/Target/VE/VEInstrInfo.td +++ b/llvm/lib/Target/VE/VEInstrInfo.td @@ -541,6 +541,27 @@ } } +// Multiclass for floating point conversion instructions. +// Used by CVS/CVD/FLT and others +multiclass CVTm opc, + RegisterClass RCo, ValueType Tyo, + RegisterClass RCi, ValueType Tyi, Operand immOp, + SDPatternOperator OpNode=null_frag> { + def r : RR { + let cy = 1; + let hasSideEffects = 0; + } + def i : RR { + let cy = 0; + let hasSideEffects = 0; + } +} + + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -719,6 +740,25 @@ defm FCMIS : RRm<"fmin.s", 0x3E, F32, f32, simm7Op32, uimm6Op32>; } +let cx = 0, cw = 0 /* sign extend */, cz = 1, sz = 0 /* round toward zero */ in +defm FIX : CVTm<"cvt.w.d.sx.rz", 0x4E, I32, i32, I64, f64, simm7Op32, fp_to_sint>; +let cx = 1, cw = 0 /* sign extend */, cz = 1, sz = 0 /* round toward zero */ in +defm FIXS : CVTm<"cvt.w.s.sx.rz", 0x4E, I32, i32, F32, f32, simm7Op32, fp_to_sint>; +let cx = 0, cz = 1, sz = 0 /* round toward zero */ in +defm FIXX : CVTm<"cvt.l.d.rz", 0x4F, I64, i64, I64, f64, simm7Op64, fp_to_sint>; +let cz = 0, sz = 0 in { + let cx = 0 in + defm FLT : CVTm<"cvt.d.w", 0x5E, I64, f64, I32, i32, simm7Op32, sint_to_fp>; + let cx = 1 in + defm FLTS : CVTm<"cvt.s.w", 0x5E, F32, f32, I32, i32, simm7Op32, sint_to_fp>; + let cx = 0 in + defm FLTX : CVTm<"cvt.d.l", 0x5F, I64, f64, I64, i64, simm7Op64, sint_to_fp>; + let cx = 0 in + defm CVS : CVTm<"cvt.s.d", 0x1F, F32, f32, I64, f64, simm7Op64, fpround>; + let cx = 0 in + defm CVD : CVTm<"cvt.d.s", 0x0F, I64, f64, F32, f32, simm7Op32, fpextend>; +} + // Load and Store instructions // As 1st step, only uses sz and imm32 to represent $addr let mayLoad = 1, hasSideEffects = 0 in { @@ -915,6 +955,10 @@ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (ADSrm1 $sy, 0), sub_i32)>; def : Pat<(i64 (zext i32:$sy)), (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (ADSUrm1 $sy, 0), sub_i32)>; +def : Pat<(i64 (fp_to_sint f32:$sy)), (FIXXr (CVDr $sy))>; + +// Cast to f32 +def : Pat<(f32 (sint_to_fp i64:$sy)), (CVSr (FLTXr i64:$sy))>; def : Pat<(i64 (anyext i32:$sy)), (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $sy, sub_i32)>; @@ -1222,6 +1266,16 @@ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_f32)), sub_f32)>; +// bitconvert +def : Pat<(f64 (bitconvert i64:$src)), (COPY_TO_REGCLASS $src, I64)>; +def : Pat<(i64 (bitconvert f64:$src)), (COPY_TO_REGCLASS $src, I64)>; + +def : Pat<(i32 (bitconvert f32:$op)), + (EXTRACT_SUBREG (SRAXri (INSERT_SUBREG (i64 (IMPLICIT_DEF)), + $op, sub_f32), 32), sub_i32)>; +def : Pat<(f32 (bitconvert i32:$op)), + (EXTRACT_SUBREG (SLLri (INSERT_SUBREG (i64 (IMPLICIT_DEF)), + $op, sub_i32), 32), sub_f32)>; // Several special pattern matches to optimize code diff --git a/llvm/test/CodeGen/VE/bitcast.ll b/llvm/test/CodeGen/VE/bitcast.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/VE/bitcast.ll @@ -0,0 +1,43 @@ +; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s + +; Function Attrs: noinline nounwind optnone +define dso_local i64 @bitcastd2l(double %x) { +; CHECK-LABEL: bitcastd2l: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: or %s11, 0, %s9 + %r = bitcast double %x to i64 + ret i64 %r +} + +; Function Attrs: noinline nounwind optnone +define dso_local double @bitcastl2d(i64 %x) { +; CHECK-LABEL: bitcastl2d: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: or %s11, 0, %s9 + %r = bitcast i64 %x to double + ret double %r +} + +; Function Attrs: noinline nounwind optnone +define dso_local float @bitcastw2f(i32 %x) { +; CHECK-LABEL: bitcastw2f: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: # kill: def $sw0 killed $sw0 def $sx0 +; CHECK-NEXT: sll %s0, %s0, 32 +; CHECK-NEXT: # kill: def $sf0 killed $sf0 killed $sx0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = bitcast i32 %x to float + ret float %r +} + +; Function Attrs: noinline nounwind optnone +define dso_local i32 @bitcastf2w(float %x) { +; CHECK-LABEL: bitcastf2w: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: # kill: def $sf0 killed $sf0 def $sx0 +; CHECK-NEXT: sra.l %s0, %s0, 32 +; CHECK-NEXT: # kill: def $sw0 killed $sw0 killed $sx0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = bitcast float %x to i32 + ret i32 %r +} diff --git a/llvm/test/CodeGen/VE/cast.ll b/llvm/test/CodeGen/VE/cast.ll --- a/llvm/test/CodeGen/VE/cast.ll +++ b/llvm/test/CodeGen/VE/cast.ll @@ -33,6 +33,96 @@ ret i64 2147483648 } +define signext i8 @d2c(double %x) { +; CHECK-LABEL: d2c: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.d.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = fptosi double %x to i8 + ret i8 %r +} + +define zeroext i8 @d2uc(double %x) { +; CHECK-LABEL: d2uc: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.d.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = fptoui double %x to i8 + ret i8 %r +} + +define signext i16 @d2s(double %x) { +; CHECK-LABEL: d2s: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.d.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = fptosi double %x to i16 + ret i16 %r +} + +define zeroext i16 @d2us(double %x) { +; CHECK-LABEL: d2us: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.d.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = fptoui double %x to i16 + ret i16 %r +} + +define i32 @d2i(double %x) { +; CHECK-LABEL: d2i: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.d.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = fptosi double %x to i32 + ret i32 %r +} + +define i32 @d2ui(double %x) { +; CHECK-LABEL: d2ui: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.l.d.rz %s0, %s0 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: or %s11, 0, %s9 + %r = fptoui double %x to i32 + ret i32 %r +} + +define i64 @d2ll(double %x) { +; CHECK-LABEL: d2ll: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.l.d.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = fptosi double %x to i64 + ret i64 %r +} + +define i64 @d2ull(double %x) { +; CHECK-LABEL: d2ull: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: lea.sl %s1, 1138753536 +; CHECK-NEXT: fcmp.d %s2, %s0, %s1 +; CHECK-NEXT: fsub.d %s1, %s0, %s1 +; CHECK-NEXT: cvt.l.d.rz %s1, %s1 +; CHECK-NEXT: lea.sl %s3, -2147483648 +; CHECK-NEXT: xor %s1, %s1, %s3 +; CHECK-NEXT: cvt.l.d.rz %s0, %s0 +; CHECK-NEXT: cmov.d.lt %s1, %s0, %s2 +; CHECK-NEXT: or %s0, 0, %s1 +; CHECK-NEXT: or %s11, 0, %s9 + %r = fptoui double %x to i64 + ret i64 %r +} + +define float @d2f(double %x) { +; CHECK-LABEL: d2f: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.s.d %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = fptrunc double %x to float + ret float %r +} + define double @d2d(double returned %0) { ; CHECK-LABEL: d2d: ; CHECK: .LBB{{[0-9]+}}_2: @@ -40,12 +130,108 @@ ret double %0 } +define signext i8 @f2c(float %x) { +; CHECK-LABEL: f2c: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.s.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = fptosi float %x to i8 + ret i8 %r +} + +define zeroext i8 @f2uc(float %x) { +; CHECK-LABEL: f2uc: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.s.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = fptoui float %x to i8 + ret i8 %r +} + +define signext i16 @f2s(float %x) { +; CHECK-LABEL: f2s: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.s.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = fptosi float %x to i16 + ret i16 %r +} + +define zeroext i16 @f2us(float %x) { +; CHECK-LABEL: f2us: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.s.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = fptoui float %x to i16 + ret i16 %r +} + +define i32 @f2i(float %x) { +; CHECK-LABEL: f2i: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.s.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = fptosi float %x to i32 + ret i32 %r +} + +define i32 @f2ui(float %x) { +; CHECK-LABEL: f2ui: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.s %s0, %s0 +; CHECK-NEXT: cvt.l.d.rz %s0, %s0 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: or %s11, 0, %s9 + %r = fptoui float %x to i32 + ret i32 %r +} + +define i64 @f2ll(float %x) { +; CHECK-LABEL: f2ll: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.s %s0, %s0 +; CHECK-NEXT: cvt.l.d.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = fptosi float %x to i64 + ret i64 %r +} + +define i64 @f2ull(float %x) { +; CHECK-LABEL: f2ull: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: lea.sl %s1, 1593835520 +; CHECK-NEXT: or %s1, 0, %s1 +; CHECK-NEXT: fcmp.s %s2, %s0, %s1 +; CHECK-NEXT: fsub.s %s1, %s0, %s1 +; CHECK-NEXT: cvt.d.s %s1, %s1 +; CHECK-NEXT: cvt.l.d.rz %s1, %s1 +; CHECK-NEXT: lea.sl %s3, -2147483648 +; CHECK-NEXT: xor %s1, %s1, %s3 +; CHECK-NEXT: cvt.d.s %s0, %s0 +; CHECK-NEXT: cvt.l.d.rz %s0, %s0 +; CHECK-NEXT: cmov.s.lt %s1, %s0, %s2 +; CHECK-NEXT: or %s0, 0, %s1 +; CHECK-NEXT: or %s11, 0, %s9 + %r = fptoui float %x to i64 + ret i64 %r +} + define float @f2f(float returned %0) { ; CHECK-LABEL: f2f: ; CHECK: .LBB{{[0-9]+}}_2: ; CHECK-NEXT: or %s11, 0, %s9 ret float %0 } + +define double @f2d(float %x) { +; CHECK-LABEL: f2d: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.s %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = fpext float %x to double + ret double %r +} + define signext i8 @ll2c(i64 %0) { ; CHECK-LABEL: ll2c: ; CHECK: .LBB{{[0-9]+}}_2: @@ -118,6 +304,25 @@ ret i64 %0 } +define float @ll2f(i64 %x) { +; CHECK-LABEL: ll2f: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.l %s0, %s0 +; CHECK-NEXT: cvt.s.d %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = sitofp i64 %x to float + ret float %r +} + +define double @ll2d(i64 %x) { +; CHECK-LABEL: ll2d: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.l %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = sitofp i64 %x to double + ret double %r +} + define signext i8 @ull2c(i64 %0) { ; CHECK-LABEL: ull2c: ; CHECK: .LBB{{[0-9]+}}_2: @@ -190,6 +395,46 @@ ret i64 %0 } +define float @ull2f(i64 %x) { +; CHECK-LABEL: ull2f: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: or %s1, 0, (0)1 +; CHECK-NEXT: cmps.l %s2, %s0, %s1 +; CHECK-NEXT: cvt.d.l %s1, %s0 +; CHECK-NEXT: cvt.s.d %s1, %s1 +; CHECK-NEXT: srl %s3, %s0, 1 +; CHECK-NEXT: and %s0, 1, %s0 +; CHECK-NEXT: or %s0, %s0, %s3 +; CHECK-NEXT: cvt.d.l %s0, %s0 +; CHECK-NEXT: cvt.s.d %s0, %s0 +; CHECK-NEXT: fadd.s %s0, %s0, %s0 +; CHECK-NEXT: cmov.l.lt %s1, %s0, %s2 +; CHECK-NEXT: or %s0, 0, %s1 +; CHECK-NEXT: or %s11, 0, %s9 + %r = uitofp i64 %x to float + ret float %r +} + +define double @ull2d(i64 %x) { +; CHECK-LABEL: ull2d: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: srl %s1, %s0, 32 +; CHECK-NEXT: lea.sl %s2, 1160773632 +; CHECK-NEXT: or %s1, %s1, %s2 +; CHECK-NEXT: lea %s2, 1048576 +; CHECK-NEXT: lea.sl %s2, -986710016(%s2) +; CHECK-NEXT: fadd.d %s1, %s1, %s2 +; CHECK-NEXT: lea %s2, -1 +; CHECK-NEXT: and %s2, %s2, (32)0 +; CHECK-NEXT: and %s0, %s0, %s2 +; CHECK-NEXT: lea.sl %s2, 1127219200 +; CHECK-NEXT: or %s0, %s0, %s2 +; CHECK-NEXT: fadd.d %s0, %s0, %s1 +; CHECK-NEXT: or %s11, 0, %s9 + %r = uitofp i64 %x to double + ret double %r +} + define signext i8 @i2c(i32 %0) { ; CHECK-LABEL: i2c: ; CHECK: .LBB{{[0-9]+}}_2: @@ -260,6 +505,24 @@ ret i64 %2 } +define float @i2f(i32 %x) { +; CHECK-LABEL: i2f: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.s.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = sitofp i32 %x to float + ret float %r +} + +define double @i2d(i32 %x) { +; CHECK-LABEL: i2d: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = sitofp i32 %x to double + ret double %r +} + define signext i8 @ui2c(i32 %0) { ; CHECK-LABEL: ui2c: ; CHECK: .LBB{{[0-9]+}}_2: @@ -330,6 +593,27 @@ ret i64 %2 } +define float @ui2f(i32 %x) { +; CHECK-LABEL: ui2f: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: cvt.d.l %s0, %s0 +; CHECK-NEXT: cvt.s.d %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = uitofp i32 %x to float + ret float %r +} + +define double @ui2d(i32 %x) { +; CHECK-LABEL: ui2d: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: cvt.d.l %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = uitofp i32 %x to double + ret double %r +} + define signext i8 @s2c(i16 signext %0) { ; CHECK-LABEL: s2c: ; CHECK: .LBB{{[0-9]+}}_2: @@ -398,6 +682,24 @@ ret i64 %2 } +define float @s2f(i16 signext %x) { +; CHECK-LABEL: s2f: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.s.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = sitofp i16 %x to float + ret float %r +} + +define double @s2d(i16 signext %x) { +; CHECK-LABEL: s2d: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = sitofp i16 %x to double + ret double %r +} + define signext i8 @us2c(i16 zeroext %0) { ; CHECK-LABEL: us2c: ; CHECK: .LBB{{[0-9]+}}_2: @@ -467,6 +769,24 @@ ret i64 %2 } +define float @us2f(i16 zeroext %x) { +; CHECK-LABEL: us2f: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.s.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = uitofp i16 %x to float + ret float %r +} + +define double @us2d(i16 zeroext %x) { +; CHECK-LABEL: us2d: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = uitofp i16 %x to double + ret double %r +} + define signext i8 @c2c(i8 returned signext %0) { ; CHECK-LABEL: c2c: ; CHECK: .LBB{{[0-9]+}}_2: @@ -533,6 +853,24 @@ ret i64 %2 } +define float @c2f(i8 signext %x) { +; CHECK-LABEL: c2f: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.s.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = sitofp i8 %x to float + ret float %r +} + +define double @c2d(i8 signext %x) { +; CHECK-LABEL: c2d: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = sitofp i8 %x to double + ret double %r +} + define signext i8 @uc2c(i8 returned zeroext %0) { ; CHECK-LABEL: uc2c: ; CHECK: .LBB{{[0-9]+}}_2: @@ -599,6 +937,24 @@ ret i64 %2 } +define float @uc2f(i8 zeroext %x) { +; CHECK-LABEL: uc2f: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.s.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = uitofp i8 %x to float + ret float %r +} + +define double @uc2d(i8 zeroext %x) { +; CHECK-LABEL: uc2d: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 + %r = uitofp i8 %x to double + ret double %r +} + ; Function Attrs: norecurse nounwind readnone define i128 @i128() { ; CHECK-LABEL: i128: diff --git a/llvm/test/CodeGen/VE/fp_to_int.ll b/llvm/test/CodeGen/VE/fp_to_int.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/VE/fp_to_int.ll @@ -0,0 +1,200 @@ +; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s + +; Function Attrs: norecurse nounwind readnone +define signext i8 @f2c(float %a) { +; CHECK-LABEL: f2c: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.s.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = fptosi float %a to i8 + ret i8 %conv +} + +; Function Attrs: norecurse nounwind readnone +define signext i16 @f2s(float %a) { +; CHECK-LABEL: f2s: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.s.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = fptosi float %a to i16 + ret i16 %conv +} + +; Function Attrs: norecurse nounwind readnone +define i32 @f2i(float %a) { +; CHECK-LABEL: f2i: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.s.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = fptosi float %a to i32 + ret i32 %conv +} + +; Function Attrs: norecurse nounwind readnone +define i64 @f2l(float %a) { +; CHECK-LABEL: f2l: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.s %s0, %s0 +; CHECK-NEXT: cvt.l.d.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = fptosi float %a to i64 + ret i64 %conv +} + +; Function Attrs: norecurse nounwind readnone +define zeroext i8 @f2uc(float %a) { +; CHECK-LABEL: f2uc: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.s.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = fptoui float %a to i8 + ret i8 %conv +} + +; Function Attrs: norecurse nounwind readnone +define zeroext i16 @f2us(float %a) { +; CHECK-LABEL: f2us: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.s.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = fptoui float %a to i16 + ret i16 %conv +} + +; Function Attrs: norecurse nounwind readnone +define i32 @f2ui(float %a) { +; CHECK-LABEL: f2ui: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.s %s0, %s0 +; CHECK-NEXT: cvt.l.d.rz %s0, %s0 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = fptoui float %a to i32 + ret i32 %conv +} + +; Function Attrs: norecurse nounwind readnone +define i64 @f2ul(float %a) { +; CHECK-LABEL: f2ul: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: lea.sl %s1, 1593835520 +; CHECK-NEXT: or %s1, 0, %s1 +; CHECK-NEXT: fcmp.s %s2, %s0, %s1 +; CHECK-NEXT: fsub.s %s1, %s0, %s1 +; CHECK-NEXT: cvt.d.s %s1, %s1 +; CHECK-NEXT: cvt.l.d.rz %s1, %s1 +; CHECK-NEXT: lea.sl %s3, -2147483648 +; CHECK-NEXT: xor %s1, %s1, %s3 +; CHECK-NEXT: cvt.d.s %s0, %s0 +; CHECK-NEXT: cvt.l.d.rz %s0, %s0 +; CHECK-NEXT: cmov.s.lt %s1, %s0, %s2 +; CHECK-NEXT: or %s0, 0, %s1 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = fptoui float %a to i64 + ret i64 %conv +} + +; Function Attrs: norecurse nounwind readnone +define signext i8 @d2c(double %a) { +; CHECK-LABEL: d2c: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.d.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = fptosi double %a to i8 + ret i8 %conv +} + +; Function Attrs: norecurse nounwind readnone +define signext i16 @d2s(double %a) { +; CHECK-LABEL: d2s: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.d.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = fptosi double %a to i16 + ret i16 %conv +} + +; Function Attrs: norecurse nounwind readnone +define i32 @d2i(double %a) { +; CHECK-LABEL: d2i: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.d.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = fptosi double %a to i32 + ret i32 %conv +} + +; Function Attrs: norecurse nounwind readnone +define i64 @d2l(double %a) { +; CHECK-LABEL: d2l: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.l.d.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = fptosi double %a to i64 + ret i64 %conv +} + +; Function Attrs: norecurse nounwind readnone +define zeroext i8 @d2uc(double %a) { +; CHECK-LABEL: d2uc: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.d.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = fptoui double %a to i8 + ret i8 %conv +} + +; Function Attrs: norecurse nounwind readnone +define zeroext i16 @d2us(double %a) { +; CHECK-LABEL: d2us: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.w.d.sx.rz %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = fptoui double %a to i16 + ret i16 %conv +} + +; Function Attrs: norecurse nounwind readnone +define i32 @d2ui(double %a) { +; CHECK-LABEL: d2ui: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.l.d.rz %s0, %s0 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = fptoui double %a to i32 + ret i32 %conv +} + +; Function Attrs: norecurse nounwind readnone +define i64 @d2ul(double %a) { +; CHECK-LABEL: d2ul: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: lea.sl %s1, 1138753536 +; CHECK-NEXT: fcmp.d %s2, %s0, %s1 +; CHECK-NEXT: fsub.d %s1, %s0, %s1 +; CHECK-NEXT: cvt.l.d.rz %s1, %s1 +; CHECK-NEXT: lea.sl %s3, -2147483648 +; CHECK-NEXT: xor %s1, %s1, %s3 +; CHECK-NEXT: cvt.l.d.rz %s0, %s0 +; CHECK-NEXT: cmov.d.lt %s1, %s0, %s2 +; CHECK-NEXT: or %s0, 0, %s1 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = fptoui double %a to i64 + ret i64 %conv +} diff --git a/llvm/test/CodeGen/VE/int_to_fp.ll b/llvm/test/CodeGen/VE/int_to_fp.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/VE/int_to_fp.ll @@ -0,0 +1,203 @@ +; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s + +; Function Attrs: norecurse nounwind readnone +define float @c2f(i8 signext %a) { +; CHECK-LABEL: c2f: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.s.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = sitofp i8 %a to float + ret float %conv +} + +; Function Attrs: norecurse nounwind readnone +define float @s2f(i16 signext %a) { +; CHECK-LABEL: s2f: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.s.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = sitofp i16 %a to float + ret float %conv +} + +; Function Attrs: norecurse nounwind readnone +define float @i2f(i32 %a) { +; CHECK-LABEL: i2f: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.s.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = sitofp i32 %a to float + ret float %conv +} + +; Function Attrs: norecurse nounwind readnone +define float @l2f(i64 %a) { +; CHECK-LABEL: l2f: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.l %s0, %s0 +; CHECK-NEXT: cvt.s.d %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = sitofp i64 %a to float + ret float %conv +} + +; Function Attrs: norecurse nounwind readnone +define float @uc2f(i8 zeroext %a) { +; CHECK-LABEL: uc2f: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.s.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = uitofp i8 %a to float + ret float %conv +} + +; Function Attrs: norecurse nounwind readnone +define float @us2f(i16 zeroext %a) { +; CHECK-LABEL: us2f: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.s.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = uitofp i16 %a to float + ret float %conv +} + +; Function Attrs: norecurse nounwind readnone +define float @ui2f(i32 %a) { +; CHECK-LABEL: ui2f: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: cvt.d.l %s0, %s0 +; CHECK-NEXT: cvt.s.d %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = uitofp i32 %a to float + ret float %conv +} + +; Function Attrs: norecurse nounwind readnone +define float @ul2f(i64 %a) { +; CHECK-LABEL: ul2f: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: or %s1, 0, (0)1 +; CHECK-NEXT: cmps.l %s2, %s0, %s1 +; CHECK-NEXT: cvt.d.l %s1, %s0 +; CHECK-NEXT: cvt.s.d %s1, %s1 +; CHECK-NEXT: srl %s3, %s0, 1 +; CHECK-NEXT: and %s0, 1, %s0 +; CHECK-NEXT: or %s0, %s0, %s3 +; CHECK-NEXT: cvt.d.l %s0, %s0 +; CHECK-NEXT: cvt.s.d %s0, %s0 +; CHECK-NEXT: fadd.s %s0, %s0, %s0 +; CHECK-NEXT: cmov.l.lt %s1, %s0, %s2 +; CHECK-NEXT: or %s0, 0, %s1 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = uitofp i64 %a to float + ret float %conv +} + +; Function Attrs: norecurse nounwind readnone +define double @c2d(i8 signext %a) { +; CHECK-LABEL: c2d: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = sitofp i8 %a to double + ret double %conv +} + +; Function Attrs: norecurse nounwind readnone +define double @s2d(i16 signext %a) { +; CHECK-LABEL: s2d: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = sitofp i16 %a to double + ret double %conv +} + +; Function Attrs: norecurse nounwind readnone +define double @i2d(i32 %a) { +; CHECK-LABEL: i2d: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = sitofp i32 %a to double + ret double %conv +} + +; Function Attrs: norecurse nounwind readnone +define double @l2d(i64 %a) { +; CHECK-LABEL: l2d: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.l %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = sitofp i64 %a to double + ret double %conv +} + +; Function Attrs: norecurse nounwind readnone +define double @uc2d(i8 zeroext %a) { +; CHECK-LABEL: uc2d: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = uitofp i8 %a to double + ret double %conv +} + +; Function Attrs: norecurse nounwind readnone +define double @us2d(i16 zeroext %a) { +; CHECK-LABEL: us2d: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: cvt.d.w %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = uitofp i16 %a to double + ret double %conv +} + +; Function Attrs: norecurse nounwind readnone +define double @ui2d(i32 %a) { +; CHECK-LABEL: ui2d: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: cvt.d.l %s0, %s0 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = uitofp i32 %a to double + ret double %conv +} + +; Function Attrs: norecurse nounwind readnone +define double @ul2d(i64 %a) { +; CHECK-LABEL: ul2d: +; CHECK: .LBB{{[0-9]+}}_2: +; CHECK-NEXT: srl %s1, %s0, 32 +; CHECK-NEXT: lea.sl %s2, 1160773632 +; CHECK-NEXT: or %s1, %s1, %s2 +; CHECK-NEXT: lea %s2, 1048576 +; CHECK-NEXT: lea.sl %s2, -986710016(%s2) +; CHECK-NEXT: fadd.d %s1, %s1, %s2 +; CHECK-NEXT: lea %s2, -1 +; CHECK-NEXT: and %s2, %s2, (32)0 +; CHECK-NEXT: and %s0, %s0, %s2 +; CHECK-NEXT: lea.sl %s2, 1127219200 +; CHECK-NEXT: or %s0, %s0, %s2 +; CHECK-NEXT: fadd.d %s0, %s0, %s1 +; CHECK-NEXT: or %s11, 0, %s9 +entry: + %conv = uitofp i64 %a to double + ret double %conv +}