From cd6f7b1e77cdfca718cf571e651c8f27bde9669f Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 13 Oct 2017 15:43:12 +0000 Subject: [PATCH] [Hexagon] Add patterns for cmpb/cmph with immediate arguments Patch by Sumanth Gundapaneni. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315692 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Hexagon/HexagonPatterns.td | 46 +++++++++++++++++++++++++++ test/CodeGen/Hexagon/cmpb-dec-imm.ll | 30 +++++++++++++++++ test/CodeGen/Hexagon/cmph-gtu.ll | 46 +++++++++++++++++++++++++++ 3 files changed, 122 insertions(+) create mode 100644 test/CodeGen/Hexagon/cmpb-dec-imm.ll create mode 100644 test/CodeGen/Hexagon/cmph-gtu.ll diff --git a/lib/Target/Hexagon/HexagonPatterns.td b/lib/Target/Hexagon/HexagonPatterns.td index f185c49b85d..72d7569076a 100644 --- a/lib/Target/Hexagon/HexagonPatterns.td +++ b/lib/Target/Hexagon/HexagonPatterns.td @@ -63,6 +63,11 @@ def IsNPow2_64H : PatLeaf<(i64 imm), [{ return isPowerOf2_64(NV) && Log2_64(NV) >= 32; }]>; +class IsUGT: PatLeaf<(i32 imm), + "uint64_t V = N->getZExtValue();" # + "return isUInt<" # Width # ">(V) && V > " # Arg # ";" +>; + def SDEC1 : SDNodeXFormgetSExtValue(); return CurDAG->getTargetConstant(V-1, SDLoc(N), MVT::i32); @@ -114,6 +119,47 @@ def : T_CMP_pat ; def : T_CMP_pat ; def : T_CMP_pat ; + +def SDTAssertZext: SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<0,1>]>; +def AssertZextSD: SDNode<"ISD::AssertZext", SDTAssertZext>; +class AssertZext: PatFrag<(ops node:$A), (AssertZextSD $A, T)>; + +multiclass Cmpb_pat { + def: Pat<(i1 (Op (and I32:$Rs, Mask), ImmPred:$I)), + (MI I32:$Rs, imm:$I)>; + def: Pat<(i1 (Op (AssertExt I32:$Rs), ImmPred:$I)), + (MI I32:$Rs, imm:$I)>; +} + +multiclass CmpbN_pat { + def: Pat<(i1 (Op (and I32:$Rs, Mask), ImmPred:$I)), + (C2_not (MI I32:$Rs, imm:$I))>; + def: Pat<(i1 (Op (AssertExt I32:$Rs), ImmPred:$I)), + (C2_not (MI I32:$Rs, imm:$I))>; +} + +multiclass CmpbND_pat { + def: Pat<(i1 (Op (and I32:$Rs, Mask), ImmPred:$I)), + (C2_not (MI I32:$Rs, (UDEC1 imm:$I)))>; + def: Pat<(i1 (Op (AssertExt I32:$Rs), ImmPred:$I)), + (C2_not (MI I32:$Rs, (UDEC1 imm:$I)))>; +} + +let AddedComplexity = 200 in { + defm: Cmpb_pat , IsUGT<8,31>, 255>; + defm: CmpbN_pat , IsUGT<8,31>, 255>; + defm: Cmpb_pat , IsUGT<32,31>, 255>; + defm: CmpbN_pat , IsUGT<32,31>, 255>; + defm: Cmpb_pat , IsUGT<32,31>, 65535>; + defm: CmpbN_pat , IsUGT<32,31>, 65535>; + defm: CmpbND_pat, IsUGT<32,32>, 255>; + defm: CmpbND_pat, IsUGT<32,32>, 65535>; +} + + def SDTHexagonI64I32I32 : SDTypeProfile<1, 2, [SDTCisVT<0, i64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>; diff --git a/test/CodeGen/Hexagon/cmpb-dec-imm.ll b/test/CodeGen/Hexagon/cmpb-dec-imm.ll new file mode 100644 index 00000000000..d3b48e6b294 --- /dev/null +++ b/test/CodeGen/Hexagon/cmpb-dec-imm.ll @@ -0,0 +1,30 @@ +; RUN: llc -march=hexagon -debug-only=isel < %s 2>&1 | FileCheck %s +; REQUIRES: asserts + +; Check that we generate 'cmpb.gtu' instruction for a byte comparision +; The "Optimized Lowered Selection" converts the "ugt with #40" to +; "ult with #41". The immediate value should be decremented to #40 +; with the selected cmpb.gtu pattern +; CHECK: setcc{{.*}}41{{.*}}setult +; CHECK: A4_cmpbgtui{{.*}}40 + +@glob = common global i8 0, align 1 + +define i32 @cmpgtudec(i32 %a0, i32 %a1) #0 { +b2: + %v3 = xor i32 %a1, %a0 + %v4 = and i32 %v3, 255 + %v5 = icmp ugt i32 %v4, 40 + br i1 %v5, label %b6, label %b8 + +b6: ; preds = %b2 + %v7 = trunc i32 %a0 to i8 + store i8 %v7, i8* @glob, align 1 + br label %b8 + +b8: ; preds = %b6, %b2 + %v9 = phi i32 [ 1, %b6 ], [ 0, %b2 ] + ret i32 %v9 +} + +attributes #0 = { nounwind } diff --git a/test/CodeGen/Hexagon/cmph-gtu.ll b/test/CodeGen/Hexagon/cmph-gtu.ll new file mode 100644 index 00000000000..f5feb7bc6fb --- /dev/null +++ b/test/CodeGen/Hexagon/cmph-gtu.ll @@ -0,0 +1,46 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s + +; Check that we generate 'cmph.gtu' instruction. +; CHECK-LABEL: @cmphgtu +; CHECK: cmph.gtu + +@glob = common global i8 0, align 1 + +define i32 @cmphgtu(i32 %a0, i32 %a1) #0 { +b2: + %v3 = xor i32 %a1, %a0 + %v4 = and i32 %v3, 65535 + %v5 = icmp ugt i32 %v4, 40 + br i1 %v5, label %b6, label %b8 + +b6: ; preds = %b2 + %v7 = trunc i32 %a0 to i8 + store i8 %v7, i8* @glob, align 1 + br label %b8 + +b8: ; preds = %b6, %b2 + %v9 = phi i32 [ 1, %b6 ], [ 0, %b2 ] + ret i32 %v9 +} + +; With zxtb, we must not generate a cmph.gtu instruction. +; CHECK-LABEL: @nocmphgtu +; CHECK-NOT: cmph.gtu +define i32 @nocmphgtu(i32 %a0, i32 %a1) #0 { +b2: + %v3 = xor i32 %a1, %a0 + %v4 = and i32 %v3, 255 + %v5 = icmp ugt i32 %v4, 40 + br i1 %v5, label %b6, label %b8 + +b6: ; preds = %b2 + %v7 = trunc i32 %a0 to i8 + store i8 %v7, i8* @glob, align 1 + br label %b8 + +b8: ; preds = %b6, %b2 + %v9 = phi i32 [ 1, %b6 ], [ 0, %b2 ] + ret i32 %v9 +} + +attributes #0 = { nounwind } -- 2.40.0