Skip to content

Commit 7a6fd49

Browse files
committed
[RISCV] Use short forward branch for ISD::ABS.
We can use short forward branch to conditionally negate if the value is negative.
1 parent ce61274 commit 7a6fd49

File tree

3 files changed

+97
-1
lines changed

3 files changed

+97
-1
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,14 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
396396
setOperationAction(ISD::CTLZ, MVT::i32, Expand);
397397
}
398398

399-
if (!RV64LegalI32 && Subtarget.is64Bit())
399+
if (!RV64LegalI32 && Subtarget.is64Bit() &&
400+
!Subtarget.hasShortForwardBranchOpt())
400401
setOperationAction(ISD::ABS, MVT::i32, Custom);
401402

403+
// We can use PseudoCCSUB to implement ABS.
404+
if (Subtarget.hasShortForwardBranchOpt())
405+
setOperationAction(ISD::ABS, XLenVT, Legal);
406+
402407
if (!Subtarget.hasVendorXTHeadCondMov())
403408
setOperationAction(ISD::SELECT, XLenVT, Custom);
404409

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,6 +1242,10 @@ def anyext_oneuse : unop_oneuse<anyext>;
12421242
def ext_oneuse : unop_oneuse<ext>;
12431243
def fpext_oneuse : unop_oneuse<any_fpextend>;
12441244

1245+
def 33signbits_node : PatLeaf<(i64 GPR:$src), [{
1246+
return CurDAG->ComputeNumSignBits(SDValue(N, 0)) > 32;
1247+
}]>;
1248+
12451249
/// Simple arithmetic operations
12461250

12471251
def : PatGprGpr<add, ADD>;
@@ -2002,6 +2006,15 @@ def : Pat<(binop_allwusers<add> GPR:$rs1, (AddiPair:$rs2)),
20022006
(AddiPairImmSmall AddiPair:$rs2))>;
20032007
}
20042008

2009+
let Predicates = [HasShortForwardBranchOpt] in
2010+
def : Pat<(XLenVT (abs GPR:$rs1)),
2011+
(PseudoCCSUB (XLenVT GPR:$rs1), (XLenVT X0), /* COND_LT */ 2,
2012+
(XLenVT GPR:$rs1), (XLenVT X0), (XLenVT GPR:$rs1))>;
2013+
let Predicates = [HasShortForwardBranchOpt, IsRV64] in
2014+
def : Pat<(sext_inreg (abs 33signbits_node:$rs1), i32),
2015+
(PseudoCCSUBW (i64 GPR:$rs1), (i64 X0), /* COND_LT */ 2,
2016+
(XLenVT GPR:$rs1), (i64 X0), (i64 GPR:$rs1))>;
2017+
20052018
//===----------------------------------------------------------------------===//
20062019
// Experimental RV64 i32 legalization patterns.
20072020
//===----------------------------------------------------------------------===//

llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,3 +1458,81 @@ entry:
14581458
%1 = select i1 %cond, i32 %C, i32 %0
14591459
ret i32 %1
14601460
}
1461+
1462+
define signext i32 @abs_i32(i32 signext %x) {
1463+
; NOSFB-LABEL: abs_i32:
1464+
; NOSFB: # %bb.0:
1465+
; NOSFB-NEXT: sraiw a1, a0, 31
1466+
; NOSFB-NEXT: xor a0, a0, a1
1467+
; NOSFB-NEXT: subw a0, a0, a1
1468+
; NOSFB-NEXT: ret
1469+
;
1470+
; RV64SFB-LABEL: abs_i32:
1471+
; RV64SFB: # %bb.0:
1472+
; RV64SFB-NEXT: bgez a0, .LBB34_2
1473+
; RV64SFB-NEXT: # %bb.1:
1474+
; RV64SFB-NEXT: negw a0, a0
1475+
; RV64SFB-NEXT: .LBB34_2:
1476+
; RV64SFB-NEXT: ret
1477+
;
1478+
; ZICOND-LABEL: abs_i32:
1479+
; ZICOND: # %bb.0:
1480+
; ZICOND-NEXT: bgez a0, .LBB34_2
1481+
; ZICOND-NEXT: # %bb.1:
1482+
; ZICOND-NEXT: negw a0, a0
1483+
; ZICOND-NEXT: .LBB34_2:
1484+
; ZICOND-NEXT: ret
1485+
;
1486+
; RV32SFB-LABEL: abs_i32:
1487+
; RV32SFB: # %bb.0:
1488+
; RV32SFB-NEXT: bgez a0, .LBB34_2
1489+
; RV32SFB-NEXT: # %bb.1:
1490+
; RV32SFB-NEXT: neg a0, a0
1491+
; RV32SFB-NEXT: .LBB34_2:
1492+
; RV32SFB-NEXT: ret
1493+
%a = call i32 @llvm.abs.i32(i32 %x, i1 false)
1494+
ret i32 %a
1495+
}
1496+
declare i32 @llvm.abs.i32(i32, i1)
1497+
1498+
define i64 @abs_i64(i64 %x) {
1499+
; NOSFB-LABEL: abs_i64:
1500+
; NOSFB: # %bb.0:
1501+
; NOSFB-NEXT: srai a1, a0, 63
1502+
; NOSFB-NEXT: xor a0, a0, a1
1503+
; NOSFB-NEXT: sub a0, a0, a1
1504+
; NOSFB-NEXT: ret
1505+
;
1506+
; RV64SFB-LABEL: abs_i64:
1507+
; RV64SFB: # %bb.0:
1508+
; RV64SFB-NEXT: bgez a0, .LBB35_2
1509+
; RV64SFB-NEXT: # %bb.1:
1510+
; RV64SFB-NEXT: neg a0, a0
1511+
; RV64SFB-NEXT: .LBB35_2:
1512+
; RV64SFB-NEXT: ret
1513+
;
1514+
; ZICOND-LABEL: abs_i64:
1515+
; ZICOND: # %bb.0:
1516+
; ZICOND-NEXT: bgez a0, .LBB35_2
1517+
; ZICOND-NEXT: # %bb.1:
1518+
; ZICOND-NEXT: neg a0, a0
1519+
; ZICOND-NEXT: .LBB35_2:
1520+
; ZICOND-NEXT: ret
1521+
;
1522+
; RV32SFB-LABEL: abs_i64:
1523+
; RV32SFB: # %bb.0:
1524+
; RV32SFB-NEXT: snez a2, a0
1525+
; RV32SFB-NEXT: add a2, a2, a1
1526+
; RV32SFB-NEXT: bgez a1, .LBB35_2
1527+
; RV32SFB-NEXT: # %bb.1:
1528+
; RV32SFB-NEXT: neg a0, a0
1529+
; RV32SFB-NEXT: .LBB35_2:
1530+
; RV32SFB-NEXT: bgez a1, .LBB35_4
1531+
; RV32SFB-NEXT: # %bb.3:
1532+
; RV32SFB-NEXT: neg a1, a2
1533+
; RV32SFB-NEXT: .LBB35_4:
1534+
; RV32SFB-NEXT: ret
1535+
%a = call i64 @llvm.abs.i64(i64 %x, i1 false)
1536+
ret i64 %a
1537+
}
1538+
declare i64 @llvm.abs.i64(i64, i1)

0 commit comments

Comments
 (0)