Index: lib/Target/Lanai/LanaiISelLowering.h =================================================================== --- lib/Target/Lanai/LanaiISelLowering.h +++ lib/Target/Lanai/LanaiISelLowering.h @@ -78,6 +78,7 @@ SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const; SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; Index: lib/Target/Lanai/LanaiISelLowering.cpp =================================================================== --- lib/Target/Lanai/LanaiISelLowering.cpp +++ lib/Target/Lanai/LanaiISelLowering.cpp @@ -84,7 +84,7 @@ setOperationAction(ISD::BR_CC, MVT::i32, Custom); setOperationAction(ISD::BR_JT, MVT::Other, Expand); - setOperationAction(ISD::BRCOND, MVT::Other, Expand); + setOperationAction(ISD::BRCOND, MVT::Other, Custom); setOperationAction(ISD::SETCC, MVT::i32, Custom); setOperationAction(ISD::SETCCE, MVT::i32, Custom); setOperationAction(ISD::SELECT, MVT::i32, Expand); @@ -178,6 +178,8 @@ switch (Op.getOpcode()) { case ISD::MUL: return LowerMUL(Op, DAG); + case ISD::BRCOND: + return LowerBRCOND(Op, DAG); case ISD::BR_CC: return LowerBR_CC(Op, DAG); case ISD::ConstantPool: @@ -868,6 +870,57 @@ } } +SDValue LanaiTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const { + SDLoc DL(Op); + // Expand brcond's setcc into its constituent parts and create a BR_CC Node. + SDValue Chain = Op.getOperand(0); + SDValue Cond = Op.getOperand(1); + + SmallVector Ops(1, Cond); + SmallPtrSet Visited; + bool FromSetcc = true; + while (!Ops.empty()) { + SDValue Op = Ops.back(); + Ops.pop_back(); + + if (!Visited.insert(Op.getNode()).second) continue; + + switch (Op.getOpcode()) { + case ISD::SETCC: + continue; + case ISD::AND: + case ISD::OR: + case ISD::SELECT: + case ISD::SELECT_CC: + case ISD::XOR: + for (unsigned i = 0, ie = Op.getNumOperands(); i != ie; ++i) { + // The condition of the select is not propagated. + if (Op.getOpcode() == ISD::SELECT && i == 0) continue; + if (Op.getOpcode() == ISD::SELECT_CC && i != 2 && i != 3) continue; + Ops.push_back(Op.getOperand(i)); + } + break; + default: + FromSetcc = false; + break; + } + if (!FromSetcc) break; + } + + if (FromSetcc) + return DAG.getNode( + ISD::BR_CC, DL, MVT::Other, Chain, DAG.getCondCode(ISD::SETNE), Cond, + DAG.getConstant(0, DL, Cond.getValueType()), Op.getOperand(2)); + + // We test only the i1 bit. Skip the AND if UNDEF. + if (!Cond.isUndef()) + Cond = DAG.getNode(ISD::AND, DL, Cond.getValueType(), Cond, + DAG.getConstant(1, DL, Cond.getValueType())); + return DAG.getNode( + ISD::BR_CC, DL, MVT::Other, Chain, DAG.getCondCode(ISD::SETNE), Cond, + DAG.getConstant(0, DL, Cond.getValueType()), Op.getOperand(2)); +} + SDValue LanaiTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const { SDValue Chain = Op.getOperand(0); SDValue Cond = Op.getOperand(1); Index: test/CodeGen/Lanai/masking_setccs.ll =================================================================== --- /dev/null +++ test/CodeGen/Lanai/masking_setccs.ll @@ -0,0 +1,39 @@ +; RUN: llc < %s | FileCheck %s + +; Test that unnecessary masking with 0x1 is not inserted. + +target datalayout = "E-m:e-p:32:32-i64:64-a:0:32-n32-S64" +target triple = "lanai" + +; CHECK-LABEL: masking: +; CHECK-NOT: mov 1 +define i32 @masking(i32 inreg %a, i32 inreg %b, i32 inreg %c, i32 inreg %d) { +entry: + %cmp = icmp ne i32 %a, 0 + %cmp1 = icmp ult i32 %a, %b + %or.cond = and i1 %cmp, %cmp1 + br i1 %or.cond, label %return, label %if.end + +if.end: ; preds = %entry + %cmp2 = icmp ne i32 %b, 0 + %cmp4 = icmp ult i32 %b, %c + %or.cond29 = and i1 %cmp2, %cmp4 + br i1 %or.cond29, label %return, label %if.end6 + +if.end6: ; preds = %if.end + %cmp7 = icmp ne i32 %c, 0 + %cmp9 = icmp ult i32 %c, %d + %or.cond30 = and i1 %cmp7, %cmp9 + br i1 %or.cond30, label %return, label %if.end11 + +if.end11: ; preds = %if.end6 + %cmp12 = icmp ne i32 %d, 0 + %cmp14 = icmp ult i32 %d, %a + %or.cond31 = and i1 %cmp12, %cmp14 + %b. = select i1 %or.cond31, i32 %b, i32 21 + ret i32 %b. + +return: ; preds = %if.end6, %if.end, %entry + %retval.0 = phi i32 [ %c, %entry ], [ %d, %if.end ], [ %a, %if.end6 ] + ret i32 %retval.0 +}