diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 5af2b6a495b8b..bf97741dbe70b 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -345,7 +345,7 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM, setOperationAction(ISD::STRICT_FSETCCS, MVT::f64, Custom); setOperationAction(ISD::BITREVERSE, MVT::i32, Legal); setOperationAction(ISD::BITREVERSE, MVT::i64, Legal); - setOperationAction(ISD::BRCOND, MVT::Other, Expand); + setOperationAction(ISD::BRCOND, MVT::Other, Custom); setOperationAction(ISD::BR_CC, MVT::i32, Custom); setOperationAction(ISD::BR_CC, MVT::i64, Custom); setOperationAction(ISD::BR_CC, MVT::f16, Custom); @@ -5004,6 +5004,22 @@ SDValue AArch64TargetLowering::LowerABS(SDValue Op, SelectionDAG &DAG) const { Cmp.getValue(1)); } +static SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) { + SDValue Chain = Op.getOperand(0); + SDValue Cond = Op.getOperand(1); + SDValue Dest = Op.getOperand(2); + + AArch64CC::CondCode CC; + if (SDValue Cmp = emitConjunction(DAG, Cond, CC)) { + SDLoc dl(Op); + SDValue CCVal = DAG.getConstant(CC, dl, MVT::i32); + return DAG.getNode(AArch64ISD::BRCOND, dl, MVT::Other, Chain, Dest, CCVal, + Cmp); + } + + return SDValue(); +} + SDValue AArch64TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { LLVM_DEBUG(dbgs() << "Custom lowering: "); @@ -5023,6 +5039,8 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op, case ISD::STRICT_FSETCC: case ISD::STRICT_FSETCCS: return LowerSETCC(Op, DAG); + case ISD::BRCOND: + return LowerBRCOND(Op, DAG); case ISD::BR_CC: return LowerBR_CC(Op, DAG); case ISD::SELECT: diff --git a/llvm/test/CodeGen/AArch64/andorbrcompare.ll b/llvm/test/CodeGen/AArch64/andorbrcompare.ll index 86b41e893dfbd..c6f98294635e0 100644 --- a/llvm/test/CodeGen/AArch64/andorbrcompare.ll +++ b/llvm/test/CodeGen/AArch64/andorbrcompare.ll @@ -6,19 +6,17 @@ declare void @dummy() define i32 @and_eq_ne_ult(i32 %s0, i32 %s1, i32 %s2, i32 %s3, i32 %s4, i32 %s5, i32* %p) { ; CHECK-LABEL: and_eq_ne_ult: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: cmp w0, w1 -; CHECK-NEXT: ccmp w2, w3, #4, eq -; CHECK-NEXT: b.ne .LBB0_3 -; CHECK-NEXT: // %bb.1: // %entry -; CHECK-NEXT: cmp w4, w5 -; CHECK-NEXT: b.lo .LBB0_3 -; CHECK-NEXT: // %bb.2: -; CHECK-NEXT: mov w0, wzr -; CHECK-NEXT: ret -; CHECK-NEXT: .LBB0_3: // %if +; CHECK-NEXT: cmp w2, w3 +; CHECK-NEXT: ccmp w0, w1, #0, ne +; CHECK-NEXT: ccmp w4, w5, #0, ne +; CHECK-NEXT: b.hs .LBB0_2 +; CHECK-NEXT: // %bb.1: // %if ; CHECK-NEXT: mov w0, #1 ; CHECK-NEXT: str w0, [x6] ; CHECK-NEXT: ret +; CHECK-NEXT: .LBB0_2: +; CHECK-NEXT: mov w0, wzr +; CHECK-NEXT: ret entry: %c0 = icmp eq i32 %s0, %s1 %c1 = icmp ne i32 %s2, %s3 @@ -38,19 +36,17 @@ else: define i32 @and_ne_ult_ule(i32 %s0, i32 %s1, i32 %s2, i32 %s3, i32 %s4, i32 %s5, i32* %p) { ; CHECK-LABEL: and_ne_ult_ule: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: cmp w0, w1 -; CHECK-NEXT: ccmp w2, w3, #2, ne -; CHECK-NEXT: b.lo .LBB1_3 -; CHECK-NEXT: // %bb.1: // %entry -; CHECK-NEXT: cmp w4, w5 -; CHECK-NEXT: b.ls .LBB1_3 -; CHECK-NEXT: // %bb.2: -; CHECK-NEXT: mov w0, wzr -; CHECK-NEXT: ret -; CHECK-NEXT: .LBB1_3: // %if +; CHECK-NEXT: cmp w2, w3 +; CHECK-NEXT: ccmp w0, w1, #4, lo +; CHECK-NEXT: ccmp w4, w5, #0, eq +; CHECK-NEXT: b.hi .LBB1_2 +; CHECK-NEXT: // %bb.1: // %if ; CHECK-NEXT: mov w0, #1 ; CHECK-NEXT: str w0, [x6] ; CHECK-NEXT: ret +; CHECK-NEXT: .LBB1_2: +; CHECK-NEXT: mov w0, wzr +; CHECK-NEXT: ret entry: %c0 = icmp ne i32 %s0, %s1 %c1 = icmp ult i32 %s2, %s3 @@ -70,19 +66,17 @@ else: define i32 @and_ult_ule_ugt(i32 %s0, i32 %s1, i32 %s2, i32 %s3, i32 %s4, i32 %s5, i32* %p) { ; CHECK-LABEL: and_ult_ule_ugt: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: cmp w0, w1 -; CHECK-NEXT: ccmp w2, w3, #2, lo -; CHECK-NEXT: b.ls .LBB2_3 -; CHECK-NEXT: // %bb.1: // %entry -; CHECK-NEXT: cmp w4, w5 -; CHECK-NEXT: b.hi .LBB2_3 -; CHECK-NEXT: // %bb.2: -; CHECK-NEXT: mov w0, wzr -; CHECK-NEXT: ret -; CHECK-NEXT: .LBB2_3: // %if +; CHECK-NEXT: cmp w2, w3 +; CHECK-NEXT: ccmp w0, w1, #2, ls +; CHECK-NEXT: ccmp w4, w5, #2, hs +; CHECK-NEXT: b.ls .LBB2_2 +; CHECK-NEXT: // %bb.1: // %if ; CHECK-NEXT: mov w0, #1 ; CHECK-NEXT: str w0, [x6] ; CHECK-NEXT: ret +; CHECK-NEXT: .LBB2_2: +; CHECK-NEXT: mov w0, wzr +; CHECK-NEXT: ret entry: %c0 = icmp ult i32 %s0, %s1 %c1 = icmp ule i32 %s2, %s3 @@ -102,19 +96,17 @@ else: define i32 @and_ule_ugt_uge(i32 %s0, i32 %s1, i32 %s2, i32 %s3, i32 %s4, i32 %s5, i32* %p) { ; CHECK-LABEL: and_ule_ugt_uge: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: cmp w0, w1 -; CHECK-NEXT: ccmp w2, w3, #0, ls -; CHECK-NEXT: b.hi .LBB3_3 -; CHECK-NEXT: // %bb.1: // %entry -; CHECK-NEXT: cmp w4, w5 -; CHECK-NEXT: b.hs .LBB3_3 -; CHECK-NEXT: // %bb.2: -; CHECK-NEXT: mov w0, wzr -; CHECK-NEXT: ret -; CHECK-NEXT: .LBB3_3: // %if +; CHECK-NEXT: cmp w2, w3 +; CHECK-NEXT: ccmp w0, w1, #2, hi +; CHECK-NEXT: ccmp w4, w5, #2, hi +; CHECK-NEXT: b.lo .LBB3_2 +; CHECK-NEXT: // %bb.1: // %if ; CHECK-NEXT: mov w0, #1 ; CHECK-NEXT: str w0, [x6] ; CHECK-NEXT: ret +; CHECK-NEXT: .LBB3_2: +; CHECK-NEXT: mov w0, wzr +; CHECK-NEXT: ret entry: %c0 = icmp ule i32 %s0, %s1 %c1 = icmp ugt i32 %s2, %s3 @@ -134,19 +126,17 @@ else: define i32 @and_ugt_uge_slt(i32 %s0, i32 %s1, i32 %s2, i32 %s3, i32 %s4, i32 %s5, i32* %p) { ; CHECK-LABEL: and_ugt_uge_slt: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: cmp w0, w1 -; CHECK-NEXT: ccmp w2, w3, #0, hi -; CHECK-NEXT: b.hs .LBB4_3 -; CHECK-NEXT: // %bb.1: // %entry -; CHECK-NEXT: cmp w4, w5 -; CHECK-NEXT: b.lt .LBB4_3 -; CHECK-NEXT: // %bb.2: -; CHECK-NEXT: mov w0, wzr -; CHECK-NEXT: ret -; CHECK-NEXT: .LBB4_3: // %if +; CHECK-NEXT: cmp w2, w3 +; CHECK-NEXT: ccmp w0, w1, #0, hs +; CHECK-NEXT: ccmp w4, w5, #8, ls +; CHECK-NEXT: b.ge .LBB4_2 +; CHECK-NEXT: // %bb.1: // %if ; CHECK-NEXT: mov w0, #1 ; CHECK-NEXT: str w0, [x6] ; CHECK-NEXT: ret +; CHECK-NEXT: .LBB4_2: +; CHECK-NEXT: mov w0, wzr +; CHECK-NEXT: ret entry: %c0 = icmp ugt i32 %s0, %s1 %c1 = icmp uge i32 %s2, %s3 @@ -166,19 +156,17 @@ else: define i32 @and_uge_slt_sle(i32 %s0, i32 %s1, i32 %s2, i32 %s3, i32 %s4, i32 %s5, i32* %p) { ; CHECK-LABEL: and_uge_slt_sle: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: cmp w0, w1 -; CHECK-NEXT: ccmp w2, w3, #0, hs -; CHECK-NEXT: b.lt .LBB5_3 -; CHECK-NEXT: // %bb.1: // %entry -; CHECK-NEXT: cmp w4, w5 -; CHECK-NEXT: b.le .LBB5_3 -; CHECK-NEXT: // %bb.2: -; CHECK-NEXT: mov w0, wzr -; CHECK-NEXT: ret -; CHECK-NEXT: .LBB5_3: // %if +; CHECK-NEXT: cmp w2, w3 +; CHECK-NEXT: ccmp w0, w1, #0, lt +; CHECK-NEXT: ccmp w4, w5, #4, lo +; CHECK-NEXT: b.gt .LBB5_2 +; CHECK-NEXT: // %bb.1: // %if ; CHECK-NEXT: mov w0, #1 ; CHECK-NEXT: str w0, [x6] ; CHECK-NEXT: ret +; CHECK-NEXT: .LBB5_2: +; CHECK-NEXT: mov w0, wzr +; CHECK-NEXT: ret entry: %c0 = icmp uge i32 %s0, %s1 %c1 = icmp slt i32 %s2, %s3 @@ -198,19 +186,17 @@ else: define i32 @and_slt_sle_sgt(i32 %s0, i32 %s1, i32 %s2, i32 %s3, i32 %s4, i32 %s5, i32* %p) { ; CHECK-LABEL: and_slt_sle_sgt: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: cmp w0, w1 -; CHECK-NEXT: ccmp w2, w3, #0, lt -; CHECK-NEXT: b.le .LBB6_3 -; CHECK-NEXT: // %bb.1: // %entry -; CHECK-NEXT: cmp w4, w5 -; CHECK-NEXT: b.gt .LBB6_3 -; CHECK-NEXT: // %bb.2: -; CHECK-NEXT: mov w0, wzr -; CHECK-NEXT: ret -; CHECK-NEXT: .LBB6_3: // %if +; CHECK-NEXT: cmp w2, w3 +; CHECK-NEXT: ccmp w0, w1, #0, le +; CHECK-NEXT: ccmp w4, w5, #0, ge +; CHECK-NEXT: b.le .LBB6_2 +; CHECK-NEXT: // %bb.1: // %if ; CHECK-NEXT: mov w0, #1 ; CHECK-NEXT: str w0, [x6] ; CHECK-NEXT: ret +; CHECK-NEXT: .LBB6_2: +; CHECK-NEXT: mov w0, wzr +; CHECK-NEXT: ret entry: %c0 = icmp slt i32 %s0, %s1 %c1 = icmp sle i32 %s2, %s3 @@ -230,19 +216,17 @@ else: define i32 @and_sle_sgt_sge(i32 %s0, i32 %s1, i32 %s2, i32 %s3, i32 %s4, i32 %s5, i32* %p) { ; CHECK-LABEL: and_sle_sgt_sge: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: cmp w0, w1 -; CHECK-NEXT: ccmp w2, w3, #4, le -; CHECK-NEXT: b.gt .LBB7_3 -; CHECK-NEXT: // %bb.1: // %entry -; CHECK-NEXT: cmp w4, w5 -; CHECK-NEXT: b.ge .LBB7_3 -; CHECK-NEXT: // %bb.2: -; CHECK-NEXT: mov w0, wzr -; CHECK-NEXT: ret -; CHECK-NEXT: .LBB7_3: // %if +; CHECK-NEXT: cmp w2, w3 +; CHECK-NEXT: ccmp w0, w1, #0, gt +; CHECK-NEXT: ccmp w4, w5, #0, gt +; CHECK-NEXT: b.lt .LBB7_2 +; CHECK-NEXT: // %bb.1: // %if ; CHECK-NEXT: mov w0, #1 ; CHECK-NEXT: str w0, [x6] ; CHECK-NEXT: ret +; CHECK-NEXT: .LBB7_2: +; CHECK-NEXT: mov w0, wzr +; CHECK-NEXT: ret entry: %c0 = icmp sle i32 %s0, %s1 %c1 = icmp sgt i32 %s2, %s3