Skip to content

Commit 91e85cc

Browse files
authored
[RISCV] Use arithmetic for select c, 0, simm12 even with zicond (#156957)
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. (Edit: While technically true, this is a bit misleading, we do this in combineSelectToBinOp which is also used in the zicond path, just further down.)
1 parent f4538cb commit 91e85cc

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::ADD, DL, VT, CondV,
9278+
DAG.getSignedConstant(-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)