[llvm] r266802 - [lanai] Add lowering for SETCCE i32.
Jacques Pienaar via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 19 12:15:25 PDT 2016
Author: jpienaar
Date: Tue Apr 19 14:15:25 2016
New Revision: 266802
URL: http://llvm.org/viewvc/llvm-project?rev=266802&view=rev
Log:
[lanai] Add lowering for SETCCE i32.
* Add lowering for SETCCE i32.
* Add test to check lowering of i64 compares uses SETCCE expansion (outside of EQ and NE).
* Fix select.ll test and immediate form selection for RI operations.
Added:
llvm/trunk/test/CodeGen/Lanai/comparisons_i64.ll
Modified:
llvm/trunk/lib/Target/Lanai/LanaiISelLowering.cpp
llvm/trunk/lib/Target/Lanai/LanaiISelLowering.h
llvm/trunk/lib/Target/Lanai/LanaiInstrInfo.td
llvm/trunk/test/CodeGen/Lanai/select.ll
Modified: llvm/trunk/lib/Target/Lanai/LanaiISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Lanai/LanaiISelLowering.cpp?rev=266802&r1=266801&r2=266802&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Lanai/LanaiISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Lanai/LanaiISelLowering.cpp Tue Apr 19 14:15:25 2016
@@ -71,6 +71,7 @@ LanaiTargetLowering::LanaiTargetLowering
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
setOperationAction(ISD::BRCOND, MVT::Other, Expand);
setOperationAction(ISD::SETCC, MVT::i32, Custom);
+ setOperationAction(ISD::SETCCE, MVT::i32, Custom);
setOperationAction(ISD::SELECT, MVT::i32, Expand);
setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
@@ -172,6 +173,8 @@ SDValue LanaiTargetLowering::LowerOperat
return LowerSELECT_CC(Op, DAG);
case ISD::SETCC:
return LowerSETCC(Op, DAG);
+ case ISD::SETCCE:
+ return LowerSETCCE(Op, DAG);
case ISD::SRL_PARTS:
return LowerSRL_PARTS(Op, DAG);
case ISD::VASTART:
@@ -779,9 +782,10 @@ SDValue LanaiTargetLowering::LowerCallRe
// Custom Lowerings
//===----------------------------------------------------------------------===//
-static LPCC::CondCode IntCondCCodeToICC(ISD::CondCode SetCCOpcode, SDLoc DL,
- SDValue &LHS, SDValue &RHS,
- SelectionDAG &DAG) {
+static LPCC::CondCode IntCondCCodeToICC(SDValue CC, SDLoc DL, SDValue &LHS,
+ SDValue &RHS, SelectionDAG &DAG) {
+ ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get();
+
// For integer, only the SETEQ, SETNE, SETLT, SETLE, SETGT, SETGE, SETULT,
// SETULE, SETUGT, and SETUGE opcodes are used (see CodeGen/ISDOpcodes.h)
// and Lanai only supports integer comparisons, so only provide definitions
@@ -845,14 +849,14 @@ static LPCC::CondCode IntCondCCodeToICC(
SDValue LanaiTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
SDValue Chain = Op.getOperand(0);
- ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
+ SDValue Cond = Op.getOperand(1);
SDValue LHS = Op.getOperand(2);
SDValue RHS = Op.getOperand(3);
SDValue Dest = Op.getOperand(4);
SDLoc DL(Op);
- SDValue TargetCC =
- DAG.getConstant(IntCondCCodeToICC(CC, DL, LHS, RHS, DAG), DL, MVT::i32);
+ LPCC::CondCode CC = IntCondCCodeToICC(Cond, DL, LHS, RHS, DAG);
+ SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32);
SDValue Flag =
DAG.getNode(LanaiISD::SET_FLAG, DL, MVT::Glue, LHS, RHS, TargetCC);
@@ -946,14 +950,27 @@ SDValue LanaiTargetLowering::LowerMUL(SD
return Res;
}
+SDValue LanaiTargetLowering::LowerSETCCE(SDValue Op, SelectionDAG &DAG) const {
+ SDValue LHS = Op.getOperand(0);
+ SDValue RHS = Op.getOperand(1);
+ SDValue Carry = Op.getOperand(2);
+ SDValue Cond = Op.getOperand(3);
+ SDLoc DL(Op);
+
+ LPCC::CondCode CC = IntCondCCodeToICC(Cond, DL, LHS, RHS, DAG);
+ SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32);
+ SDValue Flag = DAG.getNode(LanaiISD::SUBBF, DL, MVT::Glue, LHS, RHS, Carry);
+ return DAG.getNode(LanaiISD::SETCC, DL, Op.getValueType(), TargetCC, Flag);
+}
+
SDValue LanaiTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
SDValue LHS = Op.getOperand(0);
SDValue RHS = Op.getOperand(1);
- ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
+ SDValue Cond = Op.getOperand(2);
SDLoc DL(Op);
- SDValue TargetCC =
- DAG.getConstant(IntCondCCodeToICC(CC, DL, LHS, RHS, DAG), DL, MVT::i32);
+ LPCC::CondCode CC = IntCondCCodeToICC(Cond, DL, LHS, RHS, DAG);
+ SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32);
SDValue Flag =
DAG.getNode(LanaiISD::SET_FLAG, DL, MVT::Glue, LHS, RHS, TargetCC);
@@ -966,11 +983,11 @@ SDValue LanaiTargetLowering::LowerSELECT
SDValue RHS = Op.getOperand(1);
SDValue TrueV = Op.getOperand(2);
SDValue FalseV = Op.getOperand(3);
- ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
+ SDValue Cond = Op.getOperand(4);
SDLoc DL(Op);
- SDValue TargetCC =
- DAG.getConstant(IntCondCCodeToICC(CC, DL, LHS, RHS, DAG), DL, MVT::i32);
+ LPCC::CondCode CC = IntCondCCodeToICC(Cond, DL, LHS, RHS, DAG);
+ SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32);
SDValue Flag =
DAG.getNode(LanaiISD::SET_FLAG, DL, MVT::Glue, LHS, RHS, TargetCC);
@@ -1084,6 +1101,8 @@ const char *LanaiTargetLowering::getTarg
return "LanaiISD::SELECT_CC";
case LanaiISD::SETCC:
return "LanaiISD::SETCC";
+ case LanaiISD::SUBBF:
+ return "LanaiISD::SUBBF";
case LanaiISD::SET_FLAG:
return "LanaiISD::SET_FLAG";
case LanaiISD::BR_CC:
Modified: llvm/trunk/lib/Target/Lanai/LanaiISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Lanai/LanaiISelLowering.h?rev=266802&r1=266801&r2=266802&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Lanai/LanaiISelLowering.h (original)
+++ llvm/trunk/lib/Target/Lanai/LanaiISelLowering.h Tue Apr 19 14:15:25 2016
@@ -38,12 +38,15 @@ enum {
// is condition code and operand 4 is flag operand.
SELECT_CC,
- // SETCC - Store the conditional to a register
+ // SETCC - Store the conditional code to a register.
SETCC,
- // SET_FLAG - Set flag compare
+ // SET_FLAG - Set flag compare.
SET_FLAG,
+ // SUBBF - Subtract with borrow that sets flags.
+ SUBBF,
+
// BR_CC - Used to glue together a conditional branch and comparison
BR_CC,
@@ -51,11 +54,11 @@ enum {
// and TargetGlobalAddress.
Wrapper,
- // Get the Higher/Lower 16 bits from a 32-bit immediate
+ // Get the Higher/Lower 16 bits from a 32-bit immediate.
HI,
LO,
- // Small 21-bit immediate in global memory
+ // Small 21-bit immediate in global memory.
SMALL
};
} // namespace LanaiISD
@@ -87,6 +90,7 @@ public:
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerSETCCE(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSRL_PARTS(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
Modified: llvm/trunk/lib/Target/Lanai/LanaiInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Lanai/LanaiInstrInfo.td?rev=266802&r1=266801&r2=266802&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Lanai/LanaiInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Lanai/LanaiInstrInfo.td Tue Apr 19 14:15:25 2016
@@ -41,12 +41,14 @@ def Call : SDNode<"LanaiISD:
SDNPVariadic]>;
def RetFlag : SDNode<"LanaiISD::RET_FLAG", SDTNone,
[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
-def CallSeqStart : SDNode<"ISD::CALLSEQ_START", SDT_LanaiCallSeqStart,
+def CallSeqStart : SDNode<"ISD::CALLSEQ_START", SDT_LanaiCallSeqStart,
[SDNPHasChain, SDNPOutGlue]>;
-def CallSeqEnd : SDNode<"ISD::CALLSEQ_END", SDT_LanaiCallSeqEnd,
+def CallSeqEnd : SDNode<"ISD::CALLSEQ_END", SDT_LanaiCallSeqEnd,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
def LanaiSetFlag : SDNode<"LanaiISD::SET_FLAG", SDT_LanaiSetFlag,
[SDNPOutGlue]>;
+def LanaiSubbF : SDNode<"LanaiISD::SUBBF", SDT_LanaiSetFlag,
+ [SDNPOutGlue, SDNPInGlue]>;
def LanaiBrCC : SDNode<"LanaiISD::BR_CC", SDT_LanaiBrCC,
[SDNPHasChain, SDNPInGlue]>;
def LanaiSelectCC : SDNode<"LanaiISD::SELECT_CC", SDT_LanaiSelectCC,
@@ -315,13 +317,13 @@ multiclass ALUlogic<bits<3> subOp, strin
// Non flag setting ALU operations
let isAsCheapAsAMove = 1, F = 0 in {
let isCommutable = 1 in {
- defm ADD_ : ALUarith<0b000, "add", add, i32lo16s, i32hi16>;
+ defm ADD_ : ALUarith<0b000, "add", add, i32lo16z, i32hi16>;
}
- defm SUB_ : ALUarith<0b010, "sub", sub, i32lo16s, i32hi16>;
+ defm SUB_ : ALUarith<0b010, "sub", sub, i32lo16z, i32hi16>;
let isCommutable = 1 in {
defm AND_ : ALUlogic<0b100, "and", and, i32lo16and, i32hi16and>;
defm OR_ : ALUlogic<0b101, "or", or, i32lo16z, i32hi16>;
- defm XOR_ : ALUlogic<0b110, "xor", xor, i32lo16s, i32hi16>;
+ defm XOR_ : ALUlogic<0b110, "xor", xor, i32lo16z, i32hi16>;
}
}
@@ -348,8 +350,8 @@ def : Pat<(sub GPR:$Rs1, i32neg16:$imm),
// Flag (incl. carry) setting addition and subtraction
let F = 1, Defs = [SR] in {
- defm ADD_F_ : ALUarith<0b000, "add.f", addc, i32lo16s, i32hi16>;
- defm SUB_F_ : ALUarith<0b010, "sub.f", subc, i32lo16s, i32hi16>;
+ defm ADD_F_ : ALUarith<0b000, "add.f", addc, i32lo16z, i32hi16>;
+ defm SUB_F_ : ALUarith<0b010, "sub.f", subc, i32lo16z, i32hi16>;
}
def : Pat<(addc GPR:$Rs1, i32lo16z:$imm),
@@ -366,8 +368,8 @@ def : Pat<(subc GPR:$Rs1, i32hi16:$imm),
// Carry using addition and subtraction
let F = 0, Uses = [SR] in {
- defm ADDC_ : ALUarith<0b001, "addc", adde, i32lo16s, i32hi16>;
- defm SUBB_ : ALUarith<0b011, "subb", sube, i32lo16s, i32hi16>;
+ defm ADDC_ : ALUarith<0b001, "addc", adde, i32lo16z, i32hi16>;
+ defm SUBB_ : ALUarith<0b011, "subb", sube, i32lo16z, i32hi16>;
}
def : Pat<(adde GPR:$Rs1, i32lo16z:$imm),
@@ -384,15 +386,27 @@ def : Pat<(sube GPR:$Rs1, i32hi16:$imm),
// Flag setting ALU operations
let isAsCheapAsAMove = 1, F = 1, Defs = [SR] in {
- defm ADDC_F_ : ALUarith<0b001, "addc.f", adde, i32lo16s, i32hi16>;
- defm SUBB_F_ : ALUarith<0b011, "subb.f", sube, i32lo16s, i32hi16>;
let isCommutable = 1 in {
defm AND_F_ : ALUlogic<0b100, "and.f", and, i32lo16and, i32hi16and>;
defm OR_F_ : ALUlogic<0b101, "or.f", or, i32lo16z, i32hi16>;
- defm XOR_F_ : ALUlogic<0b110, "xor.f", xor, i32lo16s, i32hi16>;
+ defm XOR_F_ : ALUlogic<0b110, "xor.f", xor, i32lo16z, i32hi16>;
}
}
+let isAsCheapAsAMove = 1, F = 1, Defs = [SR], Uses = [SR] in {
+ defm ADDC_F_ : ALUarith<0b001, "addc.f", adde, i32lo16z, i32hi16>;
+ defm SUBB_F_ : ALUarith<0b011, "subb.f", sube, i32lo16z, i32hi16>;
+}
+
+def : Pat<(LanaiSubbF GPR:$Rs1, GPR:$Rs2),
+ (SUBB_F_R GPR:$Rs1, GPR:$Rs2)>;
+
+def : Pat<(LanaiSubbF GPR:$Rs1, i32lo16z:$imm),
+ (SUBB_F_I_LO GPR:$Rs1, i32lo16z:$imm)>;
+
+def : Pat<(LanaiSubbF GPR:$Rs1, i32hi16:$imm),
+ (SUBB_F_I_HI GPR:$Rs1, i32hi16:$imm)>;
+
def : InstAlias<"mov $src, $dst", (ADD_R GPR:$dst, GPR:$src, R0)>;
let isAsCheapAsAMove = 1, Rs1 = R0.Num, isCodeGenOnly = 1, H = 1, F = 0,
@@ -401,7 +415,7 @@ let isAsCheapAsAMove = 1, Rs1 = R0.Num,
"mov\t$imm16, $Rd",
[(set GPR:$Rd, i32hi16:$imm16)]>;
-def : InstAlias<"mov $imm16, $dst", (ADD_I_LO GPR:$dst, R0, i32lo16s:$imm16)>;
+def : InstAlias<"mov $imm16, $dst", (ADD_I_LO GPR:$dst, R0, i32lo16z:$imm16)>;
def : InstAlias<"mov $imm16, $dst", (ADD_I_HI GPR:$dst, R0, i32hi16:$imm16)>;
def : InstAlias<"mov $imm16, $dst",
(AND_I_LO GPR:$dst, R1, i32lo16and:$imm16)>;
@@ -693,9 +707,9 @@ multiclass SF<bits<3> op2Val, string Asm
!strconcat(AsmStr, "\t$Rs1, $Rs2, %r0"),
[(LanaiSetFlag (i32 GPR:$Rs1), (i32 GPR:$Rs2))]>;
let F = 1, Rd = R0.Num, H = 0, Defs = [SR] in
- def _RI : InstRI<op2Val, (outs), (ins GPR:$Rs1, i32lo16s:$imm16),
+ def _RI : InstRI<op2Val, (outs), (ins GPR:$Rs1, i32lo16z:$imm16),
!strconcat(AsmStr, "\t$Rs1, $imm16, %r0"),
- [(LanaiSetFlag (i32 GPR:$Rs1), i32lo16s:$imm16)]>;
+ [(LanaiSetFlag (i32 GPR:$Rs1), i32lo16z:$imm16)]>;
}
let isCodeGenOnly = 1 in {
defm SFSUB_F : SF<0b010, "sub.f">;
@@ -820,9 +834,6 @@ let isCodeGenOnly = 1 in
// Non-Instruction Patterns
//===----------------------------------------------------------------------===//
-// signed 16-bit immediate
-def : Pat<(i32 i32lo16s:$imm), (MOVHI imm:$imm)>;
-
// i32 0 and R0 can be used interchangeably.
def : Pat<(i32 0), (i32 R0)>;
// i32 -1 and R1 can be used interchangeably.
Added: llvm/trunk/test/CodeGen/Lanai/comparisons_i64.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Lanai/comparisons_i64.ll?rev=266802&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Lanai/comparisons_i64.ll (added)
+++ llvm/trunk/test/CodeGen/Lanai/comparisons_i64.ll Tue Apr 19 14:15:25 2016
@@ -0,0 +1,108 @@
+; RUN: llc < %s | FileCheck %s
+
+; Test that basic 64-bit integer comparison operations assemble as expected.
+
+target datalayout = "E-m:e-p:32:32-i64:64-a:0:32-n32-S64"
+target triple = "lanai"
+
+; CHECK-LABEL: eq_i64:
+; CHECK: xor
+; CHECK: xor
+; CHECK: or.f
+; CHECK-NEXT: seq
+define i32 @eq_i64(i64 inreg %x, i64 inreg %y) {
+ %a = icmp eq i64 %x, %y
+ %b = zext i1 %a to i32
+ ret i32 %b
+}
+
+; CHECK-LABEL: ne_i64:
+; CHECK: xor
+; CHECK: xor
+; CHECK: or.f
+; CHECK-NEXT: sne
+define i32 @ne_i64(i64 inreg %x, i64 inreg %y) {
+ %a = icmp ne i64 %x, %y
+ %b = zext i1 %a to i32
+ ret i32 %b
+}
+
+; CHECK-LABEL: slt_i64:
+; CHECK: sub.f %r7, %r19, %r3
+; CHECK: subb.f %r6, %r18, %r3
+; CHECK-NEXT: slt
+define i32 @slt_i64(i64 inreg %x, i64 inreg %y) {
+ %a = icmp slt i64 %x, %y
+ %b = zext i1 %a to i32
+ ret i32 %b
+}
+
+; CHECK-LABEL: sle_i64:
+; CHECK: sub.f %r19, %r7, %r3
+; CHECK: subb.f %r18, %r6, %r3
+; CHECK-NEXT: sge %rv
+define i32 @sle_i64(i64 inreg %x, i64 inreg %y) {
+ %a = icmp sle i64 %x, %y
+ %b = zext i1 %a to i32
+ ret i32 %b
+}
+
+; CHECK-LABEL: ult_i64:
+; CHECK: sub.f %r7, %r19, %r3
+; CHECK: subb.f %r6, %r18, %r3
+; CHECK-NEXT: sult %rv
+define i32 @ult_i64(i64 inreg %x, i64 inreg %y) {
+ %a = icmp ult i64 %x, %y
+ %b = zext i1 %a to i32
+ ret i32 %b
+}
+
+; CHECK-LABEL: ule_i64:
+; CHECK: sub.f %r19, %r7, %r3
+; CHECK: subb.f %r18, %r6, %r3
+; CHECK-NEXT: suge %rv
+define i32 @ule_i64(i64 inreg %x, i64 inreg %y) {
+ %a = icmp ule i64 %x, %y
+ %b = zext i1 %a to i32
+ ret i32 %b
+}
+
+; CHECK-LABEL: sgt_i64:
+; CHECK: sub.f %r19, %r7, %r3
+; CHECK: subb.f %r18, %r6, %r3
+; CHECK-NEXT: slt %rv
+define i32 @sgt_i64(i64 inreg %x, i64 inreg %y) {
+ %a = icmp sgt i64 %x, %y
+ %b = zext i1 %a to i32
+ ret i32 %b
+}
+
+; CHECK-LABEL: sge_i64:
+; CHECK: sub.f %r7, %r19, %r3
+; CHECK: subb.f %r6, %r18, %r3
+; CHECK-NEXT: sge %rv
+define i32 @sge_i64(i64 inreg %x, i64 inreg %y) {
+ %a = icmp sge i64 %x, %y
+ %b = zext i1 %a to i32
+ ret i32 %b
+}
+
+; CHECK-LABEL: ugt_i64:
+; CHECK: sub.f %r19, %r7, %r3
+; CHECK: subb.f %r18, %r6, %r3
+; CHECK-NEXT: sult %rv
+define i32 @ugt_i64(i64 inreg %x, i64 inreg %y) {
+ %a = icmp ugt i64 %x, %y
+ %b = zext i1 %a to i32
+ ret i32 %b
+}
+
+; CHECK-LABEL: uge_i64:
+; CHECK: sub.f %r7, %r19, %r3
+; CHECK: subb.f %r6, %r18, %r3
+; CHECK-NEXT: suge %rv
+define i32 @uge_i64(i64 inreg %x, i64 inreg %y) {
+ %a = icmp uge i64 %x, %y
+ %b = zext i1 %a to i32
+ ret i32 %b
+}
Modified: llvm/trunk/test/CodeGen/Lanai/select.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Lanai/select.ll?rev=266802&r1=266801&r2=266802&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Lanai/select.ll (original)
+++ llvm/trunk/test/CodeGen/Lanai/select.ll Tue Apr 19 14:15:25 2016
@@ -8,7 +8,7 @@ target triple = "lanai"
; CHECK-LABEL: select_i32_bool:
; CHECK: sub.f %r6, 0x0, %r0
; CHECK: sel.ne %r7, %r18, %rv
-define i32 @select_i32_bool(i1 inreg %a, i32 inreg %b, i32 inreg %c) {
+define i32 @select_i32_bool(i1 zeroext inreg %a, i32 inreg %b, i32 inreg %c) {
%cond = select i1 %a, i32 %b, i32 %c
ret i32 %cond
}
More information about the llvm-commits
mailing list