diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp index 4b61f588f18c8..83108653397fb 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -1705,8 +1705,10 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, setOperationAction(ISD::FP16_TO_FP, MVT::f128, Expand); setOperationAction(ISD::FP_TO_FP16, MVT::f128, Expand); - setOperationAction(ISD::BITCAST, MVT::f32, Expand); - setOperationAction(ISD::BITCAST, MVT::i32, Expand); + setOperationAction(ISD::BITCAST, MVT::f32, + Subtarget->isVIS3() ? Legal : Expand); + setOperationAction(ISD::BITCAST, MVT::i32, + Subtarget->isVIS3() ? Legal : Expand); // Sparc has no select or setcc: expand to SELECT_CC. setOperationAction(ISD::SELECT, MVT::i32, Expand); @@ -1744,8 +1746,10 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, } if (Subtarget->is64Bit()) { - setOperationAction(ISD::BITCAST, MVT::f64, Expand); - setOperationAction(ISD::BITCAST, MVT::i64, Expand); + setOperationAction(ISD::BITCAST, MVT::f64, + Subtarget->isVIS3() ? Legal : Expand); + setOperationAction(ISD::BITCAST, MVT::i64, + Subtarget->isVIS3() ? Legal : Expand); setOperationAction(ISD::SELECT, MVT::i64, Expand); setOperationAction(ISD::SETCC, MVT::i64, Expand); setOperationAction(ISD::BR_CC, MVT::i64, Custom); diff --git a/llvm/lib/Target/Sparc/SparcInstrVIS.td b/llvm/lib/Target/Sparc/SparcInstrVIS.td index 78f50888b5508..fdb3468a70392 100644 --- a/llvm/lib/Target/Sparc/SparcInstrVIS.td +++ b/llvm/lib/Target/Sparc/SparcInstrVIS.td @@ -259,14 +259,14 @@ def LZCNT : VISInstFormat<0b000010111, (outs I64Regs:$rd), (ins I64Regs:$rs2), "lzcnt $rs2, $rd">; let rs1 = 0 in { -def MOVSTOSW : VISInstFormat<0b100010011, (outs I64Regs:$rd), - (ins DFPRegs:$rs2), "movstosw $rs2, $rd">; -def MOVSTOUW : VISInstFormat<0b100010001, (outs I64Regs:$rd), - (ins DFPRegs:$rs2), "movstouw $rs2, $rd">; +def MOVSTOSW : VISInstFormat<0b100010011, (outs IntRegs:$rd), + (ins FPRegs:$rs2), "movstosw $rs2, $rd">; +def MOVSTOUW : VISInstFormat<0b100010001, (outs IntRegs:$rd), + (ins FPRegs:$rs2), "movstouw $rs2, $rd">; def MOVDTOX : VISInstFormat<0b100010000, (outs I64Regs:$rd), (ins DFPRegs:$rs2), "movdtox $rs2, $rd">; -def MOVWTOS : VISInstFormat<0b100011001, (outs DFPRegs:$rd), - (ins I64Regs:$rs2), "movwtos $rs2, $rd">; +def MOVWTOS : VISInstFormat<0b100011001, (outs FPRegs:$rd), + (ins IntRegs:$rs2), "movwtos $rs2, $rd">; def MOVXTOD : VISInstFormat<0b100011000, (outs DFPRegs:$rd), (ins I64Regs:$rs2), "movxtod $rs2, $rd">; } @@ -304,4 +304,11 @@ def : Pat<(i64 (ctlz_zero_undef i64:$src)), (LZCNT $src)>; // in V8+ mode. def : Pat<(i32 (ctlz i32:$src)), (ADDri (LZCNT (SRLri $src, 0)), (i32 -32))>; def : Pat<(i32 (ctlz_zero_undef i32:$src)), (ADDri (LZCNT (SRLri $src, 0)), (i32 -32))>; + +def : Pat<(i32 (bitconvert f32:$src)), (MOVSTOUW $src)>; +def : Pat<(i64 (zanyext (i32 (bitconvert f32:$src)))), (MOVSTOUW $src)>; +def : Pat<(i64 (sext (i32 (bitconvert f32:$src)))), (MOVSTOSW $src)>; +def : Pat<(f32 (bitconvert i32:$src)), (MOVWTOS $src)>; +def : Pat<(i64 (bitconvert f64:$src)), (MOVDTOX $src)>; +def : Pat<(f64 (bitconvert i64:$src)), (MOVXTOD $src)>; } // Predicates = [HasVIS3] diff --git a/llvm/test/CodeGen/SPARC/bitcast.ll b/llvm/test/CodeGen/SPARC/bitcast.ll new file mode 100644 index 0000000000000..ab13f86105cfe --- /dev/null +++ b/llvm/test/CodeGen/SPARC/bitcast.ll @@ -0,0 +1,139 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc < %s -mtriple=sparcv9 | FileCheck %s -check-prefix=V9 +; RUN: llc < %s -mtriple=sparcv9 -mattr=vis3 | FileCheck %s -check-prefix=VIS3 + +define i32 @stow(float %float) nounwind { +; V9-LABEL: stow: +; V9: ! %bb.0: +; V9-NEXT: add %sp, -144, %sp +; V9-NEXT: st %f1, [%sp+2187] +; V9-NEXT: ld [%sp+2187], %o0 +; V9-NEXT: retl +; V9-NEXT: add %sp, 144, %sp +; +; VIS3-LABEL: stow: +; VIS3: ! %bb.0: +; VIS3-NEXT: retl +; VIS3-NEXT: movstouw %f1, %o0 + %w = bitcast float %float to i32 + ret i32 %w +} + +define zeroext i32 @stouw(float %float) nounwind { +; V9-LABEL: stouw: +; V9: ! %bb.0: +; V9-NEXT: add %sp, -144, %sp +; V9-NEXT: st %f1, [%sp+2187] +; V9-NEXT: ld [%sp+2187], %o0 +; V9-NEXT: retl +; V9-NEXT: add %sp, 144, %sp +; +; VIS3-LABEL: stouw: +; VIS3: ! %bb.0: +; VIS3-NEXT: retl +; VIS3-NEXT: movstouw %f1, %o0 + %uw = bitcast float %float to i32 + ret i32 %uw +} + +define signext i32 @stosw(float %float) nounwind { +; V9-LABEL: stosw: +; V9: ! %bb.0: +; V9-NEXT: add %sp, -144, %sp +; V9-NEXT: st %f1, [%sp+2187] +; V9-NEXT: ldsw [%sp+2187], %o0 +; V9-NEXT: retl +; V9-NEXT: add %sp, 144, %sp +; +; VIS3-LABEL: stosw: +; VIS3: ! %bb.0: +; VIS3-NEXT: retl +; VIS3-NEXT: movstosw %f1, %o0 + %sw = bitcast float %float to i32 + ret i32 %sw +} + +define float @wtos(i32 %w) nounwind { +; V9-LABEL: wtos: +; V9: ! %bb.0: +; V9-NEXT: add %sp, -144, %sp +; V9-NEXT: st %o0, [%sp+2187] +; V9-NEXT: ld [%sp+2187], %f0 +; V9-NEXT: retl +; V9-NEXT: add %sp, 144, %sp +; +; VIS3-LABEL: wtos: +; VIS3: ! %bb.0: +; VIS3-NEXT: retl +; VIS3-NEXT: movwtos %o0, %f0 + %float = bitcast i32 %w to float + ret float %float +} + +define float @uwtos(i32 zeroext %uw) nounwind { +; V9-LABEL: uwtos: +; V9: ! %bb.0: +; V9-NEXT: add %sp, -144, %sp +; V9-NEXT: st %o0, [%sp+2187] +; V9-NEXT: ld [%sp+2187], %f0 +; V9-NEXT: retl +; V9-NEXT: add %sp, 144, %sp +; +; VIS3-LABEL: uwtos: +; VIS3: ! %bb.0: +; VIS3-NEXT: retl +; VIS3-NEXT: movwtos %o0, %f0 + %float = bitcast i32 %uw to float + ret float %float +} + +define float @swtos(i32 signext %sw) nounwind { +; V9-LABEL: swtos: +; V9: ! %bb.0: +; V9-NEXT: add %sp, -144, %sp +; V9-NEXT: st %o0, [%sp+2187] +; V9-NEXT: ld [%sp+2187], %f0 +; V9-NEXT: retl +; V9-NEXT: add %sp, 144, %sp +; +; VIS3-LABEL: swtos: +; VIS3: ! %bb.0: +; VIS3-NEXT: retl +; VIS3-NEXT: movwtos %o0, %f0 + %float = bitcast i32 %sw to float + ret float %float +} + +define i64 @dtox(double %double) nounwind { +; V9-LABEL: dtox: +; V9: ! %bb.0: +; V9-NEXT: add %sp, -144, %sp +; V9-NEXT: std %f0, [%sp+2183] +; V9-NEXT: ldx [%sp+2183], %o0 +; V9-NEXT: retl +; V9-NEXT: add %sp, 144, %sp +; +; VIS3-LABEL: dtox: +; VIS3: ! %bb.0: +; VIS3-NEXT: retl +; VIS3-NEXT: movdtox %f0, %o0 + %x = bitcast double %double to i64 + ret i64 %x +} + +define double @xtod(i64 %x) nounwind { +; V9-LABEL: xtod: +; V9: ! %bb.0: +; V9-NEXT: add %sp, -144, %sp +; V9-NEXT: stx %o0, [%sp+2183] +; V9-NEXT: ldd [%sp+2183], %f0 +; V9-NEXT: retl +; V9-NEXT: add %sp, 144, %sp +; +; VIS3-LABEL: xtod: +; VIS3: ! %bb.0: +; VIS3-NEXT: retl +; VIS3-NEXT: movxtod %o0, %f0 + %double = bitcast i64 %x to double + ret double %double +}