From: Stefan Maksimovic Date: Mon, 16 Oct 2017 13:18:21 +0000 (+0000) Subject: [mips] Provide alternate predicates for constant synthesis X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=83e0923cac39651920c308a9ca442aca92b0c19c;p=llvm [mips] Provide alternate predicates for constant synthesis Ordering of patterns should not be of importance anymore since the predicates used are mutually exclusive now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315901 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index 75a0ca30c11..1f869db4efe 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -1006,20 +1006,14 @@ let DecoderNamespace = "MicroMips" in { // MicroMips arbitrary patterns that map to one or more instructions //===----------------------------------------------------------------------===// -def : MipsPat<(i32 immLi16:$imm), - (LI16_MM immLi16:$imm)>; - -let AdditionalPredicates = [InMicroMips] in -defm : MaterializeImms; - -let Predicates = [InMicroMips] in { +let AdditionalPredicates = [InMicroMips] in { def : MipsPat<(i32 immLi16:$imm), (LI16_MM immLi16:$imm)>; - def : MipsPat<(i32 immSExt16:$imm), - (ADDiu_MM ZERO, immSExt16:$imm)>; - def : MipsPat<(i32 immZExt16:$imm), - (ORi_MM ZERO, immZExt16:$imm)>; + defm : MaterializeImms; +} + +let Predicates = [InMicroMips] in { def : MipsPat<(not GPRMM16:$in), (NOT16_MM GPRMM16:$in)>; def : MipsPat<(not GPR32:$in), diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index fbb8e33f40e..c4c3eb760c5 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -1222,6 +1222,20 @@ def immZExtRange2To64 : PatLeaf<(imm), [{ (N->getZExtValue() <= 64); }]>; +def ORiPred : PatLeaf<(imm), [{ + return isUInt<16>(N->getZExtValue()) && !isInt<16>(N->getSExtValue()); +}], LO16>; + +def LUiPred : PatLeaf<(imm), [{ + int64_t Val = N->getSExtValue(); + return !isInt<16>(Val) && isInt<32>(Val) && !(Val & 0xffff); +}]>; + +def LUiORiPred : PatLeaf<(imm), [{ + int64_t SVal = N->getSExtValue(); + return isInt<32>(SVal) && (SVal & 0xffff); +}]>; + // Mips Address Mode! SDNode frameindex could possibily be a match // since load and store instructions from stack used it. def addr : @@ -2716,15 +2730,20 @@ multiclass MaterializeImms { -// Small immediates -def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>; -def : MipsPat<(VT immZExt16:$imm), (ORiOp ZEROReg, imm:$imm)>; +// Constant synthesis previously relied on the ordering of the patterns below. +// By making the predicates they use non-overlapping, the patterns were +// reordered so that the effect of the newly introduced predicates can be +// observed. + +// Arbitrary immediates +def : MipsPat<(VT LUiORiPred:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>; // Bits 32-16 set, sign/zero extended. -def : MipsPat<(VT immSExt32Low16Zero:$imm), (LUiOp (HI16 imm:$imm))>; +def : MipsPat<(VT LUiPred:$imm), (LUiOp (HI16 imm:$imm))>; -// Arbitrary immediates -def : MipsPat<(VT immSExt32:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>; +// Small immediates +def : MipsPat<(VT ORiPred:$imm), (ORiOp ZEROReg, imm:$imm)>; +def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>; } let AdditionalPredicates = [NotInMicroMips] in diff --git a/test/CodeGen/Mips/constMaterialization.ll b/test/CodeGen/Mips/constMaterialization.ll new file mode 100644 index 00000000000..f34c70efa7a --- /dev/null +++ b/test/CodeGen/Mips/constMaterialization.ll @@ -0,0 +1,136 @@ +; RUN: llc -march=mips < %s | FileCheck %s -check-prefixes=ALL,MIPS +; RUN: llc -march=mips < %s -mattr=+micromips | FileCheck %s -check-prefixes=ALL,MM + +; Test the patterns used for constant materialization. + +; Constants generated using li16 +define i32 @Li16LowBoundary() { +entry: + ; ALL-LABEL: Li16LowBoundary: + ; MIPS: addiu $2, $zero, -1 + ; MM: li16 $2, -1 + ; ALL-NOT: lui + ; ALL-NOT: ori + ; MIPS-NOT: li16 + ; MM-NOT: addiu + + ret i32 -1 +} + +define i32 @Li16HighBoundary() { +entry: + ; ALL-LABEL: Li16HighBoundary: + ; MIPS: addiu $2, $zero, 126 + ; MM: li16 $2, 126 + ; ALL-NOT: lui + ; ALL-NOT: ori + ; MM-NOT: addiu + ; MIPS-NOT: li16 + + ret i32 126 +} + +; Constants generated using addiu +define i32 @AddiuLowBoundary() { +entry: + ; ALL-LABEL: AddiuLowBoundary: + ; ALL: addiu $2, $zero, -32768 + ; ALL-NOT: lui + ; ALL-NOT: ori + ; ALL-NOT: li16 + + ret i32 -32768 +} + +define i32 @AddiuZero() { +entry: + ; ALL-LABEL: AddiuZero: + ; MIPS: addiu $2, $zero, 0 + ; MM: li16 $2, 0 + ; ALL-NOT: lui + ; ALL-NOT: ori + ; MIPS-NOT: li16 + ; MM-NOT: addiu + + ret i32 0 +} + +define i32 @AddiuHighBoundary() { +entry: + ; ALL-LABEL: AddiuHighBoundary: + ; ALL: addiu $2, $zero, 32767 + ; ALL-NOT: lui + ; ALL-NOT: ori + ; ALL-NOT: li16 + + ret i32 32767 +} + +; Constants generated using ori +define i32 @OriLowBoundary() { +entry: + ; ALL-LABEL: OriLowBoundary: + ; ALL: ori $2, $zero, 32768 + ; ALL-NOT: addiu + ; ALL-NOT: lui + ; ALL-NOT: li16 + + ret i32 32768 +} + +define i32 @OriHighBoundary() { +entry: + ; ALL-LABEL: OriHighBoundary: + ; ALL: ori $2, $zero, 65535 + ; ALL-NOT: addiu + ; ALL-NOT: lui + ; ALL-NOT: li16 + + ret i32 65535 +} + +; Constants generated using lui +define i32 @LuiPositive() { +entry: + ; ALL-LABEL: LuiPositive: + ; ALL: lui $2, 1 + ; ALL-NOT: addiu + ; ALL-NOT: ori + ; ALL-NOT: li16 + + ret i32 65536 +} + +define i32 @LuiNegative() { +entry: + ; ALL-LABEL: LuiNegative: + ; ALL: lui $2, 65535 + ; ALL-NOT: addiu + ; ALL-NOT: ori + ; ALL-NOT: li16 + + ret i32 -65536 +} + +; Constants generated using a combination of lui and ori +define i32 @LuiWithLowBitsSet() { +entry: + ; ALL-LABEL: LuiWithLowBitsSet: + ; ALL: lui $1, 1 + ; ALL: ori $2, $1, 1 + ; ALL-NOT: addiu + ; ALL-NOT: li16 + + ret i32 65537 +} + +define i32 @BelowAddiuLowBoundary() { +entry: + ; ALL-LABEL: BelowAddiuLowBoundary: + ; ALL: lui $1, 65535 + ; ALL: ori $2, $1, 32767 + ; ALL-NOT: addiu + ; ALL-NOT: li16 + + ret i32 -32769 +}