From 733681d3bd25f2bf43419cca3017b8185f1baf81 Mon Sep 17 00:00:00 2001 From: Sid Manning Date: Thu, 25 Sep 2014 13:09:54 +0000 Subject: [PATCH] Add missing attributes !cmp.[eq,gt,gtu] instructions. These instructions do not indicate they are extendable or the number of bits in the extendable operand. Rename to match architected names. Add a testcase for the intrinsics. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218453 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Hexagon/HexagonInstrInfoV4.td | 62 +++++++++++++---------- lib/Target/Hexagon/HexagonIntrinsics.td | 5 ++ lib/Target/Hexagon/HexagonIntrinsicsV4.td | 9 ++-- test/CodeGen/Hexagon/cmp-not.ll | 50 ++++++++++++++++++ 4 files changed, 96 insertions(+), 30 deletions(-) create mode 100644 test/CodeGen/Hexagon/cmp-not.ll diff --git a/lib/Target/Hexagon/HexagonInstrInfoV4.td b/lib/Target/Hexagon/HexagonInstrInfoV4.td index db5b7eaa68f..d39f7d7e6c7 100644 --- a/lib/Target/Hexagon/HexagonInstrInfoV4.td +++ b/lib/Target/Hexagon/HexagonInstrInfoV4.td @@ -2130,6 +2130,42 @@ let Predicates = [HasV4T, UseMEMOP] in { // incorrect code for negative numbers. // Pd=cmpb.eq(Rs,#u8) +let isCompare = 1, isExtendable = 1, opExtendable = 2, hasSideEffects = 0, + validSubTargets = HasV4SubT in +class CMP_NOT_REG_IMM op, Operand ImmOp, + list Pattern> + : ALU32Inst <(outs PredRegs:$dst), (ins IntRegs:$src1, ImmOp:$src2), + "$dst = !cmp."#OpName#"($src1, #$src2)", + Pattern, + "", ALU32_2op_tc_2early_SLOT0123> { + bits<2> dst; + bits<5> src1; + bits<10> src2; + + let IClass = 0b0111; + let Inst{27-24} = 0b0101; + let Inst{23-22} = op; + let Inst{20-16} = src1; + let Inst{21} = !if (!eq(OpName, "gtu"), 0b0, src2{9}); + let Inst{13-5} = src2{8-0}; + let Inst{4-2} = 0b100; + let Inst{1-0} = dst; +} + +let opExtentBits = 10, isExtentSigned = 1 in { +def C4_cmpneqi : CMP_NOT_REG_IMM <"eq", 0b00, s10Ext, [(set (i1 PredRegs:$dst), + (setne (i32 IntRegs:$src1), s10ExtPred:$src2))]>; + +def C4_cmpltei : CMP_NOT_REG_IMM <"gt", 0b01, s10Ext, [(set (i1 PredRegs:$dst), + (not (setgt (i32 IntRegs:$src1), s10ExtPred:$src2)))]>; + +} +let opExtentBits = 9 in +def C4_cmplteui : CMP_NOT_REG_IMM <"gtu", 0b10, u9Ext, [(set (i1 PredRegs:$dst), + (not (setugt (i32 IntRegs:$src1), u9ExtPred:$src2)))]>; + + + // p=!cmp.eq(r1,r2) let isCompare = 1, validSubTargets = HasV4SubT in def CMPnotEQ_rr : ALU32_rr<(outs PredRegs:$dst), @@ -2139,15 +2175,6 @@ def CMPnotEQ_rr : ALU32_rr<(outs PredRegs:$dst), (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2)))]>, Requires<[HasV4T]>; -// p=!cmp.eq(r1,#s10) -let isCompare = 1, validSubTargets = HasV4SubT in -def CMPnotEQ_ri : ALU32_ri<(outs PredRegs:$dst), - (ins IntRegs:$src1, s10Ext:$src2), - "$dst = !cmp.eq($src1, #$src2)", - [(set (i1 PredRegs:$dst), - (setne (i32 IntRegs:$src1), s10ImmPred:$src2))]>, - Requires<[HasV4T]>; - // p=!cmp.gt(r1,r2) let isCompare = 1, validSubTargets = HasV4SubT in def CMPnotGT_rr : ALU32_rr<(outs PredRegs:$dst), @@ -2157,14 +2184,6 @@ def CMPnotGT_rr : ALU32_rr<(outs PredRegs:$dst), (not (setgt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>, Requires<[HasV4T]>; -// p=!cmp.gt(r1,#s10) -let isCompare = 1, validSubTargets = HasV4SubT in -def CMPnotGT_ri : ALU32_ri<(outs PredRegs:$dst), - (ins IntRegs:$src1, s10Ext:$src2), - "$dst = !cmp.gt($src1, #$src2)", - [(set (i1 PredRegs:$dst), - (not (setgt (i32 IntRegs:$src1), s10ImmPred:$src2)))]>, - Requires<[HasV4T]>; // p=!cmp.gtu(r1,r2) let isCompare = 1, validSubTargets = HasV4SubT in @@ -2175,15 +2194,6 @@ def CMPnotGTU_rr : ALU32_rr<(outs PredRegs:$dst), (not (setugt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>, Requires<[HasV4T]>; -// p=!cmp.gtu(r1,#u9) -let isCompare = 1, validSubTargets = HasV4SubT in -def CMPnotGTU_ri : ALU32_ri<(outs PredRegs:$dst), - (ins IntRegs:$src1, u9Ext:$src2), - "$dst = !cmp.gtu($src1, #$src2)", - [(set (i1 PredRegs:$dst), - (not (setugt (i32 IntRegs:$src1), u9ImmPred:$src2)))]>, - Requires<[HasV4T]>; - let isCompare = 1, validSubTargets = HasV4SubT in def CMPbEQri_V4 : MInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u8Imm:$src2), diff --git a/lib/Target/Hexagon/HexagonIntrinsics.td b/lib/Target/Hexagon/HexagonIntrinsics.td index 99f59d5ea66..b3385d8e99f 100644 --- a/lib/Target/Hexagon/HexagonIntrinsics.td +++ b/lib/Target/Hexagon/HexagonIntrinsics.td @@ -1843,6 +1843,11 @@ class si_MInst_didi !strconcat("$dst = ", !strconcat(opc , "($src1, $src2)")), [(set IntRegs:$dst, (IntID DoubleRegs:$src1, DoubleRegs:$src2))]>; + +class T_RI_pat + : Pat<(IntID (i32 IntRegs:$Rs), imm:$It), + (MI IntRegs:$Rs, imm:$It)>; + // // LDInst classes. // diff --git a/lib/Target/Hexagon/HexagonIntrinsicsV4.td b/lib/Target/Hexagon/HexagonIntrinsicsV4.td index dd28ebb5723..77b148b9f2b 100644 --- a/lib/Target/Hexagon/HexagonIntrinsicsV4.td +++ b/lib/Target/Hexagon/HexagonIntrinsicsV4.td @@ -217,12 +217,13 @@ def Hexagon_A4_combineri : di_ALU32_sis8 <"combine", int_hexagon_A4_combineri>; // ALU32 / PRED / Conditional Sign Extend. // ALU32 / PRED / Conditional Zero Extend. // ALU32 / PRED / Compare. -def Hexagon_C4_cmpneq : qi_neg_ALU32_sisi <"cmp.eq", int_hexagon_C4_cmpneq>; -def Hexagon_C4_cmpneqi : qi_neg_ALU32_sis10 <"cmp.eq", int_hexagon_C4_cmpneqi>; -def Hexagon_C4_cmplte : qi_neg_ALU32_sisi <"cmp.gt", int_hexagon_C4_cmplte>; def Hexagon_C4_cmpltei : qi_neg_ALU32_sis10 <"cmp.gt", int_hexagon_C4_cmpltei>; +def Hexagon_C4_cmplte : qi_neg_ALU32_sisi <"cmp.gt", int_hexagon_C4_cmplte>; def Hexagon_C4_cmplteu : qi_neg_ALU32_sisi <"cmp.gtu",int_hexagon_C4_cmplteu>; -def Hexagon_C4_cmplteui: qi_neg_ALU32_siu9 <"cmp.gtu",int_hexagon_C4_cmplteui>; + +def: T_RI_pat; +def: T_RI_pat; +def: T_RI_pat; // ALU32 / PRED / cmpare To General Register. def Hexagon_A4_rcmpneq : si_neg_ALU32_sisi <"cmp.eq", int_hexagon_A4_rcmpneq>; diff --git a/test/CodeGen/Hexagon/cmp-not.ll b/test/CodeGen/Hexagon/cmp-not.ll new file mode 100644 index 00000000000..abcddc38b23 --- /dev/null +++ b/test/CodeGen/Hexagon/cmp-not.ll @@ -0,0 +1,50 @@ +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s +; Check that we generate matching compare insn. + +; Function Attrs: nounwind +define i32 @neqi(i32 %argc) #0 { +entry: + %p = alloca i8, align 1 + %0 = tail call i1 @llvm.hexagon.C4.cmpneqi(i32 %argc, i32 512) + %conv = zext i1 %0 to i8 + store volatile i8 %conv, i8* %p, align 1 + %p.0.p.0. = load volatile i8* %p, align 1 + %conv1 = zext i8 %p.0.p.0. to i32 + ret i32 %conv1 +} +; CHECK: p{{[0-3]}}{{ *}} = !cmp.eq(r{{[0-9]+}}, ##512) + +; Function Attrs: nounwind readnone +declare i1 @llvm.hexagon.C4.cmpneqi(i32, i32) #1 + +; Function Attrs: nounwind +define i32 @ngti(i32 %argc) #0 { +entry: + %p = alloca i8, align 1 + %0 = tail call i1 @llvm.hexagon.C4.cmpltei(i32 %argc, i32 4) + %conv = zext i1 %0 to i8 + store volatile i8 %conv, i8* %p, align 1 + %p.0.p.0. = load volatile i8* %p, align 1 + %conv1 = zext i8 %p.0.p.0. to i32 + ret i32 %conv1 +} +; CHECK: p{{[0-3]}}{{ *}} = !cmp.gt(r{{[0-9]+}}, #4) + +; Function Attrs: nounwind readnone +declare i1 @llvm.hexagon.C4.cmpltei(i32, i32) #1 + +; Function Attrs: nounwind +define i32 @ngtui(i32 %argc) #0 { +entry: + %p = alloca i8, align 1 + %0 = tail call i1 @llvm.hexagon.C4.cmplteui(i32 %argc, i32 4) + %conv = zext i1 %0 to i8 + store volatile i8 %conv, i8* %p, align 1 + %p.0.p.0. = load volatile i8* %p, align 1 + %conv1 = zext i8 %p.0.p.0. to i32 + ret i32 %conv1 +} +; CHECK: p{{[0-3]}}{{ *}} = !cmp.gtu(r{{[0-9]+}}, #4) + +; Function Attrs: nounwind readnone +declare i1 @llvm.hexagon.C4.cmplteui(i32, i32) #1