Skip to content
Merged
29 changes: 25 additions & 4 deletions llvm/lib/Target/Sparc/SparcISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/DiagnosticInfo.h"
Expand Down Expand Up @@ -1737,6 +1738,11 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::SUBC, MVT::i32, Legal);
setOperationAction(ISD::SUBE, MVT::i32, Legal);

if (Subtarget->isVIS3()) {
setOperationAction(ISD::ADDC, MVT::i64, Legal);
setOperationAction(ISD::ADDE, MVT::i64, Legal);
}

if (Subtarget->is64Bit()) {
setOperationAction(ISD::BITCAST, MVT::f64, Expand);
setOperationAction(ISD::BITCAST, MVT::i64, Expand);
Expand All @@ -1748,7 +1754,8 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::CTPOP, MVT::i64,
Subtarget->usePopc() ? Legal : Expand);
setOperationAction(ISD::CTTZ , MVT::i64, Expand);
setOperationAction(ISD::CTLZ , MVT::i64, Expand);
setOperationAction(ISD::CTLZ, MVT::i64,
Subtarget->isVIS3() ? Legal : Expand);
setOperationAction(ISD::BSWAP, MVT::i64, Expand);
setOperationAction(ISD::ROTL , MVT::i64, Expand);
setOperationAction(ISD::ROTR , MVT::i64, Expand);
Expand Down Expand Up @@ -1810,7 +1817,8 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::FREM , MVT::f32, Expand);
setOperationAction(ISD::FMA , MVT::f32, Expand);
setOperationAction(ISD::CTTZ , MVT::i32, Expand);
setOperationAction(ISD::CTLZ , MVT::i32, Expand);
setOperationAction(ISD::CTLZ, MVT::i32,
Subtarget->isVIS3() ? Promote : Expand);
setOperationAction(ISD::ROTL , MVT::i32, Expand);
setOperationAction(ISD::ROTR , MVT::i32, Expand);
setOperationAction(ISD::BSWAP, MVT::i32, Expand);
Expand Down Expand Up @@ -1849,8 +1857,10 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
if (Subtarget->is64Bit()) {
setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
setOperationAction(ISD::MULHU, MVT::i64, Expand);
setOperationAction(ISD::MULHS, MVT::i64, Expand);
setOperationAction(ISD::MULHU, MVT::i64,
Subtarget->isVIS3() ? Legal : Expand);
setOperationAction(ISD::MULHS, MVT::i64,
Subtarget->isVIS3() ? Legal : Expand);

setOperationAction(ISD::SHL_PARTS, MVT::i64, Expand);
setOperationAction(ISD::SRA_PARTS, MVT::i64, Expand);
Expand Down Expand Up @@ -1981,6 +1991,11 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
if (Subtarget->hasLeonCycleCounter())
setOperationAction(ISD::READCYCLECOUNTER, MVT::i64, Custom);

if (Subtarget->isVIS3()) {
setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Promote);
setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i64, Legal);
}

setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);

setMinFunctionAlignment(Align(4));
Expand Down Expand Up @@ -3560,6 +3575,12 @@ bool SparcTargetLowering::useLoadStackGuardNode(const Module &M) const {
return true;
}

bool SparcTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
bool ForCodeSize) const {
return Subtarget->isVIS() && (VT == MVT::f32 || VT == MVT::f64) &&
Imm.isZero();
}

// Override to disable global variable loading on Linux.
void SparcTargetLowering::insertSSPDeclarations(Module &M) const {
if (!Subtarget->isTargetLinux())
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/Sparc/SparcISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ namespace llvm {
return VT != MVT::f128;
}

bool isFPImmLegal(const APFloat &Imm, EVT VT,
bool ForCodeSize) const override;

bool shouldInsertFencesForAtomic(const Instruction *I) const override {
// FIXME: We insert fences for each atomics and generate
// sub-optimal code for PSO/TSO. (Approximately nobody uses any
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/Sparc/SparcInstr64Bit.td
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,11 @@ def : Pat<(and i64:$lhs, (not i64:$rhs)), (ANDNrr $lhs, $rhs)>;
def : Pat<(or i64:$lhs, (not i64:$rhs)), (ORNrr $lhs, $rhs)>;
def : Pat<(not (xor i64:$lhs, i64:$rhs)), (XNORrr $lhs, $rhs)>;

def : Pat<(addc i64:$lhs, i64:$rhs), (ADDCCrr $lhs, $rhs)>, Requires<[HasVIS3]>;
def : Pat<(add i64:$lhs, i64:$rhs), (ADDrr $lhs, $rhs)>;
def : Pat<(sub i64:$lhs, i64:$rhs), (SUBrr $lhs, $rhs)>;

def : Pat<(addc i64:$lhs, (i64 simm13:$rhs)), (ADDCCri $lhs, imm:$rhs)>, Requires<[HasVIS3]>;
def : Pat<(add i64:$lhs, (i64 simm13:$rhs)), (ADDri $lhs, imm:$rhs)>;
def : Pat<(sub i64:$lhs, (i64 simm13:$rhs)), (SUBri $lhs, imm:$rhs)>;

Expand Down
35 changes: 33 additions & 2 deletions llvm/lib/Target/Sparc/SparcInstrVIS.td
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ class VISInst2<bits<9> opfval, string OpcStr, RegisterClass RC = DFPRegs>
!strconcat(OpcStr, " $rs2, $rd")>;

// For VIS Instructions with only rd operand.
let Constraints = "$rd = $f", rs1 = 0, rs2 = 0 in
let rs1 = 0, rs2 = 0 in
class VISInstD<bits<9> opfval, string OpcStr, RegisterClass RC = DFPRegs>
: VISInstFormat<opfval,
(outs RC:$rd), (ins RC:$f),
(outs RC:$rd), (ins),
!strconcat(OpcStr, " $rd")>;

// VIS 1 Instructions
Expand Down Expand Up @@ -277,3 +277,34 @@ def UMULXHI : VISInst<0b000010110, "umulxhi", I64Regs>;
def XMULX : VISInst<0b100010101, "xmulx", I64Regs>;
def XMULXHI : VISInst<0b100010110, "xmulxhi", I64Regs>;
} // Predicates = [IsVIS3]

// FP immediate patterns.
def fpimm0 : FPImmLeaf<fAny, [{return Imm.isExactlyValue(+0.0);}]>;
def fpnegimm0 : FPImmLeaf<fAny, [{return Imm.isExactlyValue(-0.0);}]>;

// VIS instruction patterns.
let Predicates = [HasVIS] in {
// Zero immediate.
def : Pat<(f64 fpimm0), (FZERO)>;
def : Pat<(f32 fpimm0), (FZEROS)>;
def : Pat<(f64 fpnegimm0), (FNEGD (FZERO))>;
def : Pat<(f32 fpnegimm0), (FNEGS (FZEROS))>;
} // Predicates = [HasVIS]

// VIS3 instruction patterns.
let Predicates = [HasVIS3] in {
def : Pat<(i64 (adde i64:$lhs, i64:$rhs)), (ADDXCCC $lhs, $rhs)>;

def : Pat<(i64 (mulhu i64:$lhs, i64:$rhs)), (UMULXHI $lhs, $rhs)>;
// Signed "MULXHI".
// Based on the formula presented in OSA2011 §7.140, but with bitops to select
// the values to be added.
// TODO: This expansion should probably be moved to DAG legalization phase.
def : Pat<(i64 (mulhs i64:$lhs, i64:$rhs)),
(SUBrr (UMULXHI $lhs, $rhs),
(ADDrr (ANDrr (SRAXri $lhs, 63), $rhs),
(ANDrr (SRAXri $rhs, 63), $lhs)))>;

def : Pat<(i64 (ctlz i64:$src)), (LZCNT $src)>;
def : Pat<(i64 (ctlz_zero_undef i64:$src)), (LZCNT $src)>;
} // Predicates = [HasVIS3]
118 changes: 118 additions & 0 deletions llvm/test/CodeGen/SPARC/2011-01-11-CC.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
; RUN: llc -mtriple=sparc %s -o - | FileCheck %s -check-prefix=V8
; RUN: llc -mtriple=sparc -mattr=v9 %s -o - | FileCheck %s -check-prefix=V9
; RUN: llc -mtriple=sparc64-unknown-linux %s -o - | FileCheck %s -check-prefix=SPARC64
; RUN: llc -mtriple=sparc64-unknown-linux -mattr=vis3 %s -o - | FileCheck %s -check-prefix=SPARC64-VIS3

define i32 @test_addx(i64 %a, i64 %b, i64 %c) nounwind {
; V8-LABEL: test_addx:
Expand Down Expand Up @@ -60,6 +61,15 @@ define i32 @test_addx(i64 %a, i64 %b, i64 %c) nounwind {
; SPARC64-NEXT: movgu %xcc, 1, %o3
; SPARC64-NEXT: retl
; SPARC64-NEXT: srl %o3, 0, %o0
;
; SPARC64-VIS3-LABEL: test_addx:
; SPARC64-VIS3: ! %bb.0: ! %entry
; SPARC64-VIS3-NEXT: mov %g0, %o3
; SPARC64-VIS3-NEXT: add %o0, %o1, %o0
; SPARC64-VIS3-NEXT: cmp %o0, %o2
; SPARC64-VIS3-NEXT: movgu %xcc, 1, %o3
; SPARC64-VIS3-NEXT: retl
; SPARC64-VIS3-NEXT: srl %o3, 0, %o0
entry:
%0 = add i64 %a, %b
%1 = icmp ugt i64 %0, %c
Expand Down Expand Up @@ -92,6 +102,13 @@ define i32 @test_select_int_icc(i32 %a, i32 %b, i32 %c) nounwind {
; SPARC64-NEXT: move %icc, %o1, %o2
; SPARC64-NEXT: retl
; SPARC64-NEXT: mov %o2, %o0
;
; SPARC64-VIS3-LABEL: test_select_int_icc:
; SPARC64-VIS3: ! %bb.0: ! %entry
; SPARC64-VIS3-NEXT: cmp %o0, 0
; SPARC64-VIS3-NEXT: move %icc, %o1, %o2
; SPARC64-VIS3-NEXT: retl
; SPARC64-VIS3-NEXT: mov %o2, %o0
entry:
%0 = icmp eq i32 %a, 0
%1 = select i1 %0, i32 %b, i32 %c
Expand Down Expand Up @@ -133,6 +150,13 @@ define float @test_select_fp_icc(i32 %a, float %f1, float %f2) nounwind {
; SPARC64-NEXT: cmp %o0, 0
; SPARC64-NEXT: retl
; SPARC64-NEXT: fmovse %icc, %f3, %f0
;
; SPARC64-VIS3-LABEL: test_select_fp_icc:
; SPARC64-VIS3: ! %bb.0: ! %entry
; SPARC64-VIS3-NEXT: fmovs %f5, %f0
; SPARC64-VIS3-NEXT: cmp %o0, 0
; SPARC64-VIS3-NEXT: retl
; SPARC64-VIS3-NEXT: fmovse %icc, %f3, %f0
entry:
%0 = icmp eq i32 %a, 0
%1 = select i1 %0, float %f1, float %f2
Expand Down Expand Up @@ -182,6 +206,13 @@ define double @test_select_dfp_icc(i32 %a, double %f1, double %f2) nounwind {
; SPARC64-NEXT: cmp %o0, 0
; SPARC64-NEXT: retl
; SPARC64-NEXT: fmovde %icc, %f2, %f0
;
; SPARC64-VIS3-LABEL: test_select_dfp_icc:
; SPARC64-VIS3: ! %bb.0: ! %entry
; SPARC64-VIS3-NEXT: fmovd %f4, %f0
; SPARC64-VIS3-NEXT: cmp %o0, 0
; SPARC64-VIS3-NEXT: retl
; SPARC64-VIS3-NEXT: fmovde %icc, %f2, %f0
entry:
%0 = icmp eq i32 %a, 0
%1 = select i1 %0, double %f1, double %f2
Expand Down Expand Up @@ -229,6 +260,17 @@ define i32 @test_select_int_fcc(float %f, i32 %a, i32 %b) nounwind {
; SPARC64-NEXT: fcmps %fcc0, %f1, %f0
; SPARC64-NEXT: retl
; SPARC64-NEXT: movne %fcc0, %o1, %o0
;
; SPARC64-VIS3-LABEL: test_select_int_fcc:
; SPARC64-VIS3: ! %bb.0: ! %entry
; SPARC64-VIS3-NEXT: sethi %h44(.LCPI4_0), %o0
; SPARC64-VIS3-NEXT: add %o0, %m44(.LCPI4_0), %o0
; SPARC64-VIS3-NEXT: sllx %o0, 12, %o0
; SPARC64-VIS3-NEXT: ld [%o0+%l44(.LCPI4_0)], %f0
; SPARC64-VIS3-NEXT: mov %o2, %o0
; SPARC64-VIS3-NEXT: fcmps %fcc0, %f1, %f0
; SPARC64-VIS3-NEXT: retl
; SPARC64-VIS3-NEXT: movne %fcc0, %o1, %o0
entry:
%0 = fcmp une float %f, 0.000000e+00
%a.b = select i1 %0, i32 %a, i32 %b
Expand Down Expand Up @@ -284,6 +326,17 @@ define float @test_select_fp_fcc(float %f, float %f1, float %f2) nounwind {
; SPARC64-NEXT: fcmps %fcc0, %f1, %f2
; SPARC64-NEXT: retl
; SPARC64-NEXT: fmovsne %fcc0, %f3, %f0
;
; SPARC64-VIS3-LABEL: test_select_fp_fcc:
; SPARC64-VIS3: ! %bb.0: ! %entry
; SPARC64-VIS3-NEXT: sethi %h44(.LCPI5_0), %o0
; SPARC64-VIS3-NEXT: add %o0, %m44(.LCPI5_0), %o0
; SPARC64-VIS3-NEXT: sllx %o0, 12, %o0
; SPARC64-VIS3-NEXT: ld [%o0+%l44(.LCPI5_0)], %f2
; SPARC64-VIS3-NEXT: fmovs %f5, %f0
; SPARC64-VIS3-NEXT: fcmps %fcc0, %f1, %f2
; SPARC64-VIS3-NEXT: retl
; SPARC64-VIS3-NEXT: fmovsne %fcc0, %f3, %f0
entry:
%0 = fcmp une float %f, 0.000000e+00
%1 = select i1 %0, float %f1, float %f2
Expand Down Expand Up @@ -352,6 +405,18 @@ define double @test_select_dfp_fcc(double %f, double %f1, double %f2) nounwind {
; SPARC64-NEXT: fmovd %f4, %f0
; SPARC64-NEXT: retl
; SPARC64-NEXT: nop
;
; SPARC64-VIS3-LABEL: test_select_dfp_fcc:
; SPARC64-VIS3: ! %bb.0: ! %entry
; SPARC64-VIS3-NEXT: sethi %h44(.LCPI6_0), %o0
; SPARC64-VIS3-NEXT: add %o0, %m44(.LCPI6_0), %o0
; SPARC64-VIS3-NEXT: sllx %o0, 12, %o0
; SPARC64-VIS3-NEXT: ldd [%o0+%l44(.LCPI6_0)], %f6
; SPARC64-VIS3-NEXT: fcmpd %fcc0, %f0, %f6
; SPARC64-VIS3-NEXT: fmovdne %fcc0, %f2, %f4
; SPARC64-VIS3-NEXT: fmovd %f4, %f0
; SPARC64-VIS3-NEXT: retl
; SPARC64-VIS3-NEXT: nop
entry:
%0 = fcmp une double %f, 0.000000e+00
%1 = select i1 %0, double %f1, double %f2
Expand Down Expand Up @@ -453,6 +518,31 @@ define i32 @test_float_cc(double %a, double %b, i32 %c, i32 %d) nounwind {
; SPARC64-NEXT: ! %bb.4: ! %exit.0
; SPARC64-NEXT: retl
; SPARC64-NEXT: mov %g0, %o0
;
; SPARC64-VIS3-LABEL: test_float_cc:
; SPARC64-VIS3: ! %bb.0: ! %entry
; SPARC64-VIS3-NEXT: sethi %h44(.LCPI7_0), %o0
; SPARC64-VIS3-NEXT: add %o0, %m44(.LCPI7_0), %o0
; SPARC64-VIS3-NEXT: sllx %o0, 12, %o0
; SPARC64-VIS3-NEXT: ldd [%o0+%l44(.LCPI7_0)], %f4
; SPARC64-VIS3-NEXT: fcmpd %fcc0, %f0, %f4
; SPARC64-VIS3-NEXT: fbuge %fcc0, .LBB7_3
; SPARC64-VIS3-NEXT: nop
; SPARC64-VIS3-NEXT: ! %bb.1: ! %loop.2
; SPARC64-VIS3-NEXT: fcmpd %fcc0, %f2, %f4
; SPARC64-VIS3-NEXT: fbule %fcc0, .LBB7_3
; SPARC64-VIS3-NEXT: nop
; SPARC64-VIS3-NEXT: ! %bb.2: ! %exit.1
; SPARC64-VIS3-NEXT: retl
; SPARC64-VIS3-NEXT: mov 1, %o0
; SPARC64-VIS3-NEXT: .LBB7_3: ! %loop
; SPARC64-VIS3-NEXT: ! =>This Inner Loop Header: Depth=1
; SPARC64-VIS3-NEXT: cmp %o2, 10
; SPARC64-VIS3-NEXT: be %icc, .LBB7_3
; SPARC64-VIS3-NEXT: nop
; SPARC64-VIS3-NEXT: ! %bb.4: ! %exit.0
; SPARC64-VIS3-NEXT: retl
; SPARC64-VIS3-NEXT: mov %g0, %o0
entry:
%0 = fcmp uge double %a, 0.000000e+00
br i1 %0, label %loop, label %loop.2
Expand Down Expand Up @@ -558,6 +648,34 @@ define void @test_adde_sube(ptr %a, ptr %b, ptr %sum, ptr %diff) nounwind {
; SPARC64-NEXT: stx %i0, [%i3]
; SPARC64-NEXT: ret
; SPARC64-NEXT: restore
;
; SPARC64-VIS3-LABEL: test_adde_sube:
; SPARC64-VIS3: .register %g2, #scratch
; SPARC64-VIS3-NEXT: ! %bb.0: ! %entry
; SPARC64-VIS3-NEXT: save %sp, -128, %sp
; SPARC64-VIS3-NEXT: ldx [%i0+8], %i4
; SPARC64-VIS3-NEXT: ldx [%i0], %i5
; SPARC64-VIS3-NEXT: ldx [%i1+8], %g2
; SPARC64-VIS3-NEXT: ldx [%i1], %i1
; SPARC64-VIS3-NEXT: addcc %i4, %g2, %g2
; SPARC64-VIS3-NEXT: addxccc %i5, %i1, %i1
; SPARC64-VIS3-NEXT: stx %i1, [%i2]
; SPARC64-VIS3-NEXT: stx %g2, [%i2+8]
; SPARC64-VIS3-NEXT: !APP
; SPARC64-VIS3-NEXT: !NO_APP
; SPARC64-VIS3-NEXT: ldx [%i0+8], %i1
; SPARC64-VIS3-NEXT: mov %g0, %i2
; SPARC64-VIS3-NEXT: ldx [%i0], %i0
; SPARC64-VIS3-NEXT: cmp %i4, %i1
; SPARC64-VIS3-NEXT: movcs %xcc, 1, %i2
; SPARC64-VIS3-NEXT: srl %i2, 0, %i2
; SPARC64-VIS3-NEXT: sub %i5, %i0, %i0
; SPARC64-VIS3-NEXT: sub %i0, %i2, %i0
; SPARC64-VIS3-NEXT: sub %i4, %i1, %i1
; SPARC64-VIS3-NEXT: stx %i1, [%i3+8]
; SPARC64-VIS3-NEXT: stx %i0, [%i3]
; SPARC64-VIS3-NEXT: ret
; SPARC64-VIS3-NEXT: restore
entry:
%0 = bitcast ptr %a to ptr
%1 = bitcast ptr %b to ptr
Expand Down
Loading
Loading