Skip to content

Commit 131c831

Browse files
committed
[RISCV] Use arithmetic for select c, 0, simm12 even with zicond
The arithmetic expansion requires fewer registers, and is often fewer instructions. The critical path does increase by (up to) one instruction. This is a sub-case of the expansion we do without zicond, but restricted specifically to the simm12 case. In the general case where the other source is a register using zicond is likely better.
1 parent e90ab31 commit 131c831

File tree

4 files changed

+120
-248
lines changed

4 files changed

+120
-248
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9240,6 +9240,10 @@ foldBinOpIntoSelectIfProfitable(SDNode *BO, SelectionDAG &DAG,
92409240
return DAG.getSelect(DL, VT, Sel.getOperand(0), NewT, NewF);
92419241
}
92429242

9243+
static bool isSimm12Constant(SDValue V) {
9244+
return isa<ConstantSDNode>(V) && V->getAsAPIntVal().isSignedIntN(12);
9245+
}
9246+
92439247
SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
92449248
SDValue CondV = Op.getOperand(0);
92459249
SDValue TrueV = Op.getOperand(1);
@@ -9261,6 +9265,20 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
92619265
// sequence or RISCVISD::SELECT_CC node (branch-based select).
92629266
if ((Subtarget.hasStdExtZicond() || Subtarget.hasVendorXVentanaCondOps()) &&
92639267
VT.isScalarInteger()) {
9268+
9269+
// select c, simm12, 0 -> andi (sub x0, c), simm12
9270+
if (isSimm12Constant(TrueV) && isNullConstant(FalseV)) {
9271+
SDValue Mask = DAG.getNegative(CondV, DL, VT);
9272+
return DAG.getNode(ISD::AND, DL, VT, TrueV, Mask);
9273+
}
9274+
9275+
// select c, 0, simm12 -> andi (addi c, -1), simm12
9276+
if (isNullConstant(TrueV) && isSimm12Constant(FalseV)) {
9277+
SDValue Mask = DAG.getNode(ISD::SUB, DL, VT, CondV,
9278+
DAG.getConstant(1, DL, XLenVT));
9279+
return DAG.getNode(ISD::AND, DL, VT, FalseV, Mask);
9280+
}
9281+
92649282
// (select c, t, 0) -> (czero_eqz t, c)
92659283
if (isNullConstant(FalseV))
92669284
return DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, TrueV, CondV);

llvm/test/CodeGen/RISCV/cmov-branch-opt.ll

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,9 @@ define signext i32 @test4(i32 signext %x, i32 signext %y, i32 signext %z) {
149149
;
150150
; CMOV-ZICOND-LABEL: test4:
151151
; CMOV-ZICOND: # %bb.0:
152-
; CMOV-ZICOND-NEXT: li a0, 3
153-
; CMOV-ZICOND-NEXT: czero.nez a0, a0, a2
152+
; CMOV-ZICOND-NEXT: snez a0, a2
153+
; CMOV-ZICOND-NEXT: addi a0, a0, -1
154+
; CMOV-ZICOND-NEXT: andi a0, a0, 3
154155
; CMOV-ZICOND-NEXT: ret
155156
;
156157
; SFB-NOZICOND-LABEL: test4:
@@ -164,8 +165,9 @@ define signext i32 @test4(i32 signext %x, i32 signext %y, i32 signext %z) {
164165
;
165166
; SFB-ZICOND-LABEL: test4:
166167
; SFB-ZICOND: # %bb.0:
167-
; SFB-ZICOND-NEXT: li a0, 3
168-
; SFB-ZICOND-NEXT: czero.nez a0, a0, a2
168+
; SFB-ZICOND-NEXT: snez a0, a2
169+
; SFB-ZICOND-NEXT: addi a0, a0, -1
170+
; SFB-ZICOND-NEXT: andi a0, a0, 3
169171
; SFB-ZICOND-NEXT: ret
170172
%c = icmp eq i32 %z, 0
171173
%a = select i1 %c, i32 3, i32 0

llvm/test/CodeGen/RISCV/select-const.ll

Lines changed: 46 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,184 +1080,74 @@ define i32 @sext_or_constant2(i32 signext %x) {
10801080

10811081

10821082
define i32 @select_0_6(i32 signext %x) {
1083-
; RV32I-LABEL: select_0_6:
1084-
; RV32I: # %bb.0:
1085-
; RV32I-NEXT: srai a0, a0, 2
1086-
; RV32I-NEXT: srli a0, a0, 30
1087-
; RV32I-NEXT: slli a0, a0, 1
1088-
; RV32I-NEXT: ret
1089-
;
1090-
; RV32IF-LABEL: select_0_6:
1091-
; RV32IF: # %bb.0:
1092-
; RV32IF-NEXT: srai a0, a0, 2
1093-
; RV32IF-NEXT: srli a0, a0, 30
1094-
; RV32IF-NEXT: slli a0, a0, 1
1095-
; RV32IF-NEXT: ret
1096-
;
1097-
; RV32ZICOND-LABEL: select_0_6:
1098-
; RV32ZICOND: # %bb.0:
1099-
; RV32ZICOND-NEXT: srli a0, a0, 31
1100-
; RV32ZICOND-NEXT: li a1, 6
1101-
; RV32ZICOND-NEXT: czero.eqz a0, a1, a0
1102-
; RV32ZICOND-NEXT: ret
1103-
;
1104-
; RV64I-LABEL: select_0_6:
1105-
; RV64I: # %bb.0:
1106-
; RV64I-NEXT: srai a0, a0, 2
1107-
; RV64I-NEXT: srli a0, a0, 62
1108-
; RV64I-NEXT: slli a0, a0, 1
1109-
; RV64I-NEXT: ret
1110-
;
1111-
; RV64IFD-LABEL: select_0_6:
1112-
; RV64IFD: # %bb.0:
1113-
; RV64IFD-NEXT: srai a0, a0, 2
1114-
; RV64IFD-NEXT: srli a0, a0, 62
1115-
; RV64IFD-NEXT: slli a0, a0, 1
1116-
; RV64IFD-NEXT: ret
1083+
; RV32-LABEL: select_0_6:
1084+
; RV32: # %bb.0:
1085+
; RV32-NEXT: srai a0, a0, 2
1086+
; RV32-NEXT: srli a0, a0, 30
1087+
; RV32-NEXT: slli a0, a0, 1
1088+
; RV32-NEXT: ret
11171089
;
1118-
; RV64ZICOND-LABEL: select_0_6:
1119-
; RV64ZICOND: # %bb.0:
1120-
; RV64ZICOND-NEXT: srli a0, a0, 63
1121-
; RV64ZICOND-NEXT: li a1, 6
1122-
; RV64ZICOND-NEXT: czero.eqz a0, a1, a0
1123-
; RV64ZICOND-NEXT: ret
1090+
; RV64-LABEL: select_0_6:
1091+
; RV64: # %bb.0:
1092+
; RV64-NEXT: srai a0, a0, 2
1093+
; RV64-NEXT: srli a0, a0, 62
1094+
; RV64-NEXT: slli a0, a0, 1
1095+
; RV64-NEXT: ret
11241096
%cmp = icmp sgt i32 %x, -1
11251097
%cond = select i1 %cmp, i32 0, i32 6
11261098
ret i32 %cond
11271099
}
11281100

11291101
define i32 @select_6_0(i32 signext %x) {
1130-
; RV32I-LABEL: select_6_0:
1131-
; RV32I: # %bb.0:
1132-
; RV32I-NEXT: srli a0, a0, 31
1133-
; RV32I-NEXT: addi a0, a0, -1
1134-
; RV32I-NEXT: andi a0, a0, 6
1135-
; RV32I-NEXT: ret
1136-
;
1137-
; RV32IF-LABEL: select_6_0:
1138-
; RV32IF: # %bb.0:
1139-
; RV32IF-NEXT: srli a0, a0, 31
1140-
; RV32IF-NEXT: addi a0, a0, -1
1141-
; RV32IF-NEXT: andi a0, a0, 6
1142-
; RV32IF-NEXT: ret
1143-
;
1144-
; RV32ZICOND-LABEL: select_6_0:
1145-
; RV32ZICOND: # %bb.0:
1146-
; RV32ZICOND-NEXT: srli a0, a0, 31
1147-
; RV32ZICOND-NEXT: li a1, 6
1148-
; RV32ZICOND-NEXT: czero.nez a0, a1, a0
1149-
; RV32ZICOND-NEXT: ret
1150-
;
1151-
; RV64I-LABEL: select_6_0:
1152-
; RV64I: # %bb.0:
1153-
; RV64I-NEXT: srli a0, a0, 63
1154-
; RV64I-NEXT: addi a0, a0, -1
1155-
; RV64I-NEXT: andi a0, a0, 6
1156-
; RV64I-NEXT: ret
1157-
;
1158-
; RV64IFD-LABEL: select_6_0:
1159-
; RV64IFD: # %bb.0:
1160-
; RV64IFD-NEXT: srli a0, a0, 63
1161-
; RV64IFD-NEXT: addi a0, a0, -1
1162-
; RV64IFD-NEXT: andi a0, a0, 6
1163-
; RV64IFD-NEXT: ret
1102+
; RV32-LABEL: select_6_0:
1103+
; RV32: # %bb.0:
1104+
; RV32-NEXT: srli a0, a0, 31
1105+
; RV32-NEXT: addi a0, a0, -1
1106+
; RV32-NEXT: andi a0, a0, 6
1107+
; RV32-NEXT: ret
11641108
;
1165-
; RV64ZICOND-LABEL: select_6_0:
1166-
; RV64ZICOND: # %bb.0:
1167-
; RV64ZICOND-NEXT: srli a0, a0, 63
1168-
; RV64ZICOND-NEXT: li a1, 6
1169-
; RV64ZICOND-NEXT: czero.nez a0, a1, a0
1170-
; RV64ZICOND-NEXT: ret
1109+
; RV64-LABEL: select_6_0:
1110+
; RV64: # %bb.0:
1111+
; RV64-NEXT: srli a0, a0, 63
1112+
; RV64-NEXT: addi a0, a0, -1
1113+
; RV64-NEXT: andi a0, a0, 6
1114+
; RV64-NEXT: ret
11711115
%cmp = icmp sgt i32 %x, -1
11721116
%cond = select i1 %cmp, i32 6, i32 0
11731117
ret i32 %cond
11741118
}
11751119

11761120
define i32 @select_0_394(i32 signext %x) {
1177-
; RV32I-LABEL: select_0_394:
1178-
; RV32I: # %bb.0:
1179-
; RV32I-NEXT: srai a0, a0, 31
1180-
; RV32I-NEXT: andi a0, a0, 394
1181-
; RV32I-NEXT: ret
1182-
;
1183-
; RV32IF-LABEL: select_0_394:
1184-
; RV32IF: # %bb.0:
1185-
; RV32IF-NEXT: srai a0, a0, 31
1186-
; RV32IF-NEXT: andi a0, a0, 394
1187-
; RV32IF-NEXT: ret
1188-
;
1189-
; RV32ZICOND-LABEL: select_0_394:
1190-
; RV32ZICOND: # %bb.0:
1191-
; RV32ZICOND-NEXT: srli a0, a0, 31
1192-
; RV32ZICOND-NEXT: li a1, 394
1193-
; RV32ZICOND-NEXT: czero.eqz a0, a1, a0
1194-
; RV32ZICOND-NEXT: ret
1195-
;
1196-
; RV64I-LABEL: select_0_394:
1197-
; RV64I: # %bb.0:
1198-
; RV64I-NEXT: srai a0, a0, 63
1199-
; RV64I-NEXT: andi a0, a0, 394
1200-
; RV64I-NEXT: ret
1201-
;
1202-
; RV64IFD-LABEL: select_0_394:
1203-
; RV64IFD: # %bb.0:
1204-
; RV64IFD-NEXT: srai a0, a0, 63
1205-
; RV64IFD-NEXT: andi a0, a0, 394
1206-
; RV64IFD-NEXT: ret
1121+
; RV32-LABEL: select_0_394:
1122+
; RV32: # %bb.0:
1123+
; RV32-NEXT: srai a0, a0, 31
1124+
; RV32-NEXT: andi a0, a0, 394
1125+
; RV32-NEXT: ret
12071126
;
1208-
; RV64ZICOND-LABEL: select_0_394:
1209-
; RV64ZICOND: # %bb.0:
1210-
; RV64ZICOND-NEXT: srli a0, a0, 63
1211-
; RV64ZICOND-NEXT: li a1, 394
1212-
; RV64ZICOND-NEXT: czero.eqz a0, a1, a0
1213-
; RV64ZICOND-NEXT: ret
1127+
; RV64-LABEL: select_0_394:
1128+
; RV64: # %bb.0:
1129+
; RV64-NEXT: srai a0, a0, 63
1130+
; RV64-NEXT: andi a0, a0, 394
1131+
; RV64-NEXT: ret
12141132
%cmp = icmp sgt i32 %x, -1
12151133
%cond = select i1 %cmp, i32 0, i32 394
12161134
ret i32 %cond
12171135
}
12181136

12191137
define i32 @select_394_0(i32 signext %x) {
1220-
; RV32I-LABEL: select_394_0:
1221-
; RV32I: # %bb.0:
1222-
; RV32I-NEXT: srli a0, a0, 31
1223-
; RV32I-NEXT: addi a0, a0, -1
1224-
; RV32I-NEXT: andi a0, a0, 394
1225-
; RV32I-NEXT: ret
1226-
;
1227-
; RV32IF-LABEL: select_394_0:
1228-
; RV32IF: # %bb.0:
1229-
; RV32IF-NEXT: srli a0, a0, 31
1230-
; RV32IF-NEXT: addi a0, a0, -1
1231-
; RV32IF-NEXT: andi a0, a0, 394
1232-
; RV32IF-NEXT: ret
1233-
;
1234-
; RV32ZICOND-LABEL: select_394_0:
1235-
; RV32ZICOND: # %bb.0:
1236-
; RV32ZICOND-NEXT: srli a0, a0, 31
1237-
; RV32ZICOND-NEXT: li a1, 394
1238-
; RV32ZICOND-NEXT: czero.nez a0, a1, a0
1239-
; RV32ZICOND-NEXT: ret
1240-
;
1241-
; RV64I-LABEL: select_394_0:
1242-
; RV64I: # %bb.0:
1243-
; RV64I-NEXT: srli a0, a0, 63
1244-
; RV64I-NEXT: addi a0, a0, -1
1245-
; RV64I-NEXT: andi a0, a0, 394
1246-
; RV64I-NEXT: ret
1247-
;
1248-
; RV64IFD-LABEL: select_394_0:
1249-
; RV64IFD: # %bb.0:
1250-
; RV64IFD-NEXT: srli a0, a0, 63
1251-
; RV64IFD-NEXT: addi a0, a0, -1
1252-
; RV64IFD-NEXT: andi a0, a0, 394
1253-
; RV64IFD-NEXT: ret
1138+
; RV32-LABEL: select_394_0:
1139+
; RV32: # %bb.0:
1140+
; RV32-NEXT: srli a0, a0, 31
1141+
; RV32-NEXT: addi a0, a0, -1
1142+
; RV32-NEXT: andi a0, a0, 394
1143+
; RV32-NEXT: ret
12541144
;
1255-
; RV64ZICOND-LABEL: select_394_0:
1256-
; RV64ZICOND: # %bb.0:
1257-
; RV64ZICOND-NEXT: srli a0, a0, 63
1258-
; RV64ZICOND-NEXT: li a1, 394
1259-
; RV64ZICOND-NEXT: czero.nez a0, a1, a0
1260-
; RV64ZICOND-NEXT: ret
1145+
; RV64-LABEL: select_394_0:
1146+
; RV64: # %bb.0:
1147+
; RV64-NEXT: srli a0, a0, 63
1148+
; RV64-NEXT: addi a0, a0, -1
1149+
; RV64-NEXT: andi a0, a0, 394
1150+
; RV64-NEXT: ret
12611151
%cmp = icmp sgt i32 %x, -1
12621152
%cond = select i1 %cmp, i32 394, i32 0
12631153
ret i32 %cond

0 commit comments

Comments
 (0)