diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td index 2cd0bc86fa2..41bcea1f059 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/lib/Target/Hexagon/HexagonInstrInfo.td @@ -3383,12 +3383,34 @@ class Storex_simple_pat : Pat<(Store Value:$Rt, (i32 IntRegs:$Rs)), (MI IntRegs:$Rs, 0, Value:$Rt)>; +// Patterns for generating stores, where the address takes different forms, +// and where the value being stored is transformed through the value modifier +// ValueMod. The address forms are same as above. +class Storexm_fi_pat + : Pat<(Store Value:$Rs, AddrFI:$fi), + (MI AddrFI:$fi, 0, (ValueMod Value:$Rs))>; +class Storexm_add_pat + : Pat<(Store Value:$Rt, (add (i32 IntRegs:$Rs), ImmPred:$Off)), + (MI IntRegs:$Rs, imm:$Off, (ValueMod Value:$Rt))>; +class Storexm_simple_pat + : Pat<(Store Value:$Rt, (i32 IntRegs:$Rs)), + (MI IntRegs:$Rs, 0, (ValueMod Value:$Rt))>; + multiclass Storex_pat { def: Storex_fi_pat ; def: Storex_add_pat ; } +multiclass Storexm_pat { + def: Storexm_fi_pat ; + def: Storexm_add_pat ; +} + // Regular stores in the DAG have two operands: value and address. // Atomic stores also have two, but they are reversed: address, value. // To use atomic stores with the patterns, they need to have their operands @@ -3397,47 +3419,38 @@ multiclass Storex_pat : PatFrag<(ops node:$val, node:$ptr), F.Fragment>; +let AddedComplexity = 20 in { + defm: Storex_pat; + defm: Storex_pat; + defm: Storex_pat; + defm: Storex_pat; + + defm: Storex_pat, I32, s11_0ExtPred, S2_storerb_io>; + defm: Storex_pat, I32, s11_1ExtPred, S2_storerh_io>; + defm: Storex_pat, I32, s11_2ExtPred, S2_storeri_io>; + defm: Storex_pat, I64, s11_3ExtPred, S2_storerd_io>; +} + +// Simple patterns should be tried with the least priority. +def: Storex_simple_pat; +def: Storex_simple_pat; +def: Storex_simple_pat; +def: Storex_simple_pat; + def: Storex_simple_pat, I32, S2_storerb_io>; def: Storex_simple_pat, I32, S2_storerh_io>; def: Storex_simple_pat, I32, S2_storeri_io>; def: Storex_simple_pat, I64, S2_storerd_io>; -def : Pat<(truncstorei8 (i32 IntRegs:$src1), ADDRriS11_0:$addr), - (S2_storerb_io AddrFI:$addr, 0, (i32 IntRegs:$src1))>; - -def : Pat<(truncstorei16 (i32 IntRegs:$src1), ADDRriS11_1:$addr), - (S2_storerh_io AddrFI:$addr, 0, (i32 IntRegs:$src1))>; - -def : Pat<(store (i32 IntRegs:$src1), ADDRriS11_2:$addr), - (S2_storeri_io AddrFI:$addr, 0, (i32 IntRegs:$src1))>; - -def : Pat<(store (i64 DoubleRegs:$src1), ADDRriS11_3:$addr), - (S2_storerd_io AddrFI:$addr, 0, (i64 DoubleRegs:$src1))>; - - -let AddedComplexity = 10 in { -def : Pat<(truncstorei8 (i32 IntRegs:$src1), (add IntRegs:$src2, - s11_0ExtPred:$offset)), - (S2_storerb_io IntRegs:$src2, s11_0ImmPred:$offset, - (i32 IntRegs:$src1))>; - -def : Pat<(truncstorei16 (i32 IntRegs:$src1), (add IntRegs:$src2, - s11_1ExtPred:$offset)), - (S2_storerh_io IntRegs:$src2, s11_1ImmPred:$offset, - (i32 IntRegs:$src1))>; - -def : Pat<(store (i32 IntRegs:$src1), (add IntRegs:$src2, - s11_2ExtPred:$offset)), - (S2_storeri_io IntRegs:$src2, s11_2ImmPred:$offset, - (i32 IntRegs:$src1))>; - -def : Pat<(store (i64 DoubleRegs:$src1), (add IntRegs:$src2, - s11_3ExtPred:$offset)), - (S2_storerd_io IntRegs:$src2, s11_3ImmPred:$offset, - (i64 DoubleRegs:$src1))>; +let AddedComplexity = 20 in { + defm: Storexm_pat; + defm: Storexm_pat; + defm: Storexm_pat; } -// memh(Rx++#s4:1)=Rt.H +def: Storexm_simple_pat; +def: Storexm_simple_pat; +def: Storexm_simple_pat; // Store predicate. let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 13, diff --git a/test/CodeGen/Hexagon/dualstore.ll b/test/CodeGen/Hexagon/dualstore.ll index f7d7e8bbe75..33d9ce9b935 100644 --- a/test/CodeGen/Hexagon/dualstore.ll +++ b/test/CodeGen/Hexagon/dualstore.ll @@ -1,17 +1,12 @@ -; RUN: llc -march=hexagon -mcpu=hexagonv4 -disable-hexagon-misched < %s | FileCheck %s +; RUN: llc -march=hexagon -disable-hexagon-misched < %s | FileCheck %s ; Check that we generate dual stores in one packet in V4 -; CHECK: memw(r{{[0-9]+}}{{ *}}+{{ *}}#{{[0-9]+}}){{ *}}={{ *}}##500000 -; CHECK-NEXT: memw(r{{[0-9]+}}{{ *}}+{{ *}}#{{[0-9]+}}){{ *}}={{ *}}##100000 -; CHECK-NEXT: } +; CHECK: memw(r{{[0-9]+}}{{ *}}+{{ *}}#{{[0-9]+}}){{ *}}= +; CHECK-NEXT: memw(r{{[0-9]+}}{{ *}}+{{ *}}#{{[0-9]+}}){{ *}}= -@Reg = global i32 0, align 4 -define i32 @main() nounwind { +define i32 @main(i32 %v, i32* %p1, i32* %p2) nounwind { entry: - %number= alloca i32, align 4 - store i32 500000, i32* %number, align 4 - %number1= alloca i32, align 4 - store i32 100000, i32* %number1, align 4 + store i32 %v, i32* %p1, align 4 + store i32 %v, i32* %p2, align 4 ret i32 0 } -