Skip to content

Commit 6a62335

Browse files
committed
[RISCV] Lower (select c, (1 << N) + 1, 0) -> (c << N) + c
1 parent cd1e45b commit 6a62335

File tree

4 files changed

+162
-56
lines changed

4 files changed

+162
-56
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9150,10 +9150,22 @@ static SDValue lowerSelectToBinOp(SDNode *N, SelectionDAG &DAG,
91509150
DAG.getNode(ISD::ADD, DL, VT, CondV, DAG.getAllOnesConstant(DL, VT));
91519151
return DAG.getNode(ISD::AND, DL, VT, Neg, DAG.getFreeze(FalseV));
91529152
}
9153-
// (select c, y, 0) -> -c & y
9154-
if (isNullConstant(FalseV) && (!HasCZero || isSimm12Constant(TrueV))) {
9155-
SDValue Neg = DAG.getNegative(CondV, DL, VT);
9156-
return DAG.getNode(ISD::AND, DL, VT, Neg, DAG.getFreeze(TrueV));
9153+
if (isNullConstant(FalseV)) {
9154+
// (select c, (1 << ShAmount) + 1, 0) -> (c << ShAmount) + c
9155+
if (auto *TrueC = dyn_cast<ConstantSDNode>(TrueV)) {
9156+
uint64_t TrueM1 = TrueC->getZExtValue() - 1;
9157+
if (isPowerOf2_64(TrueM1)) {
9158+
unsigned ShAmount = Log2_64(TrueM1);
9159+
if (Subtarget.hasShlAdd(ShAmount))
9160+
return DAG.getNode(RISCVISD::SHL_ADD, DL, VT, CondV,
9161+
DAG.getConstant(ShAmount, DL, VT), CondV);
9162+
}
9163+
}
9164+
// (select c, y, 0) -> -c & y
9165+
if (!HasCZero || isSimm12Constant(TrueV)) {
9166+
SDValue Neg = DAG.getNegative(CondV, DL, VT);
9167+
return DAG.getNode(ISD::AND, DL, VT, Neg, DAG.getFreeze(TrueV));
9168+
}
91579169
}
91589170
}
91599171

llvm/test/CodeGen/RISCV/rv32zba.ll

Lines changed: 99 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,64 +1138,130 @@ define i32 @mul_neg8(i32 %a) {
11381138
}
11391139

11401140
define i32 @select3i32(i1 zeroext %x) {
1141-
; CHECK-LABEL: select3i32:
1142-
; CHECK: # %bb.0:
1143-
; CHECK-NEXT: neg a0, a0
1144-
; CHECK-NEXT: andi a0, a0, 3
1145-
; CHECK-NEXT: ret
1141+
; RV32I-LABEL: select3i32:
1142+
; RV32I: # %bb.0:
1143+
; RV32I-NEXT: neg a0, a0
1144+
; RV32I-NEXT: andi a0, a0, 3
1145+
; RV32I-NEXT: ret
1146+
;
1147+
; RV32ZBA-LABEL: select3i32:
1148+
; RV32ZBA: # %bb.0:
1149+
; RV32ZBA-NEXT: sh1add a0, a0, a0
1150+
; RV32ZBA-NEXT: ret
1151+
;
1152+
; RV32XANDESPERF-LABEL: select3i32:
1153+
; RV32XANDESPERF: # %bb.0:
1154+
; RV32XANDESPERF-NEXT: nds.lea.h a0, a0, a0
1155+
; RV32XANDESPERF-NEXT: ret
11461156
%select = select i1 %x, i32 3, i32 0
11471157
ret i32 %select
11481158
}
11491159

11501160
define i32 @select5i32(i1 zeroext %x) {
1151-
; CHECK-LABEL: select5i32:
1152-
; CHECK: # %bb.0:
1153-
; CHECK-NEXT: neg a0, a0
1154-
; CHECK-NEXT: andi a0, a0, 5
1155-
; CHECK-NEXT: ret
1161+
; RV32I-LABEL: select5i32:
1162+
; RV32I: # %bb.0:
1163+
; RV32I-NEXT: neg a0, a0
1164+
; RV32I-NEXT: andi a0, a0, 5
1165+
; RV32I-NEXT: ret
1166+
;
1167+
; RV32ZBA-LABEL: select5i32:
1168+
; RV32ZBA: # %bb.0:
1169+
; RV32ZBA-NEXT: sh2add a0, a0, a0
1170+
; RV32ZBA-NEXT: ret
1171+
;
1172+
; RV32XANDESPERF-LABEL: select5i32:
1173+
; RV32XANDESPERF: # %bb.0:
1174+
; RV32XANDESPERF-NEXT: nds.lea.w a0, a0, a0
1175+
; RV32XANDESPERF-NEXT: ret
11561176
%select = select i1 %x, i32 5, i32 0
11571177
ret i32 %select
11581178
}
11591179

11601180
define i32 @select9i32(i1 zeroext %x) {
1161-
; CHECK-LABEL: select9i32:
1162-
; CHECK: # %bb.0:
1163-
; CHECK-NEXT: neg a0, a0
1164-
; CHECK-NEXT: andi a0, a0, 9
1165-
; CHECK-NEXT: ret
1181+
; RV32I-LABEL: select9i32:
1182+
; RV32I: # %bb.0:
1183+
; RV32I-NEXT: neg a0, a0
1184+
; RV32I-NEXT: andi a0, a0, 9
1185+
; RV32I-NEXT: ret
1186+
;
1187+
; RV32ZBA-LABEL: select9i32:
1188+
; RV32ZBA: # %bb.0:
1189+
; RV32ZBA-NEXT: sh3add a0, a0, a0
1190+
; RV32ZBA-NEXT: ret
1191+
;
1192+
; RV32XANDESPERF-LABEL: select9i32:
1193+
; RV32XANDESPERF: # %bb.0:
1194+
; RV32XANDESPERF-NEXT: nds.lea.d a0, a0, a0
1195+
; RV32XANDESPERF-NEXT: ret
11661196
%select = select i1 %x, i32 9, i32 0
11671197
ret i32 %select
11681198
}
11691199

11701200
define i64 @select3i64(i1 zeroext %x) {
1171-
; CHECK-LABEL: select3i64:
1172-
; CHECK: # %bb.0:
1173-
; CHECK-NEXT: neg a0, a0
1174-
; CHECK-NEXT: andi a0, a0, 3
1175-
; CHECK-NEXT: li a1, 0
1176-
; CHECK-NEXT: ret
1201+
; RV32I-LABEL: select3i64:
1202+
; RV32I: # %bb.0:
1203+
; RV32I-NEXT: neg a0, a0
1204+
; RV32I-NEXT: andi a0, a0, 3
1205+
; RV32I-NEXT: li a1, 0
1206+
; RV32I-NEXT: ret
1207+
;
1208+
; RV32ZBA-LABEL: select3i64:
1209+
; RV32ZBA: # %bb.0:
1210+
; RV32ZBA-NEXT: sh1add a0, a0, a0
1211+
; RV32ZBA-NEXT: li a1, 0
1212+
; RV32ZBA-NEXT: ret
1213+
;
1214+
; RV32XANDESPERF-LABEL: select3i64:
1215+
; RV32XANDESPERF: # %bb.0:
1216+
; RV32XANDESPERF-NEXT: nds.lea.h a0, a0, a0
1217+
; RV32XANDESPERF-NEXT: li a1, 0
1218+
; RV32XANDESPERF-NEXT: ret
11771219
%select = select i1 %x, i64 3, i64 0
11781220
ret i64 %select
11791221
}
11801222

11811223
define i64 @select5i64(i1 zeroext %x) {
1182-
; CHECK-LABEL: select5i64:
1183-
; CHECK: # %bb.0:
1184-
; CHECK-NEXT: neg a0, a0
1185-
; CHECK-NEXT: andi a0, a0, 5
1186-
; CHECK-NEXT: li a1, 0
1187-
; CHECK-NEXT: ret
1224+
; RV32I-LABEL: select5i64:
1225+
; RV32I: # %bb.0:
1226+
; RV32I-NEXT: neg a0, a0
1227+
; RV32I-NEXT: andi a0, a0, 5
1228+
; RV32I-NEXT: li a1, 0
1229+
; RV32I-NEXT: ret
1230+
;
1231+
; RV32ZBA-LABEL: select5i64:
1232+
; RV32ZBA: # %bb.0:
1233+
; RV32ZBA-NEXT: sh2add a0, a0, a0
1234+
; RV32ZBA-NEXT: li a1, 0
1235+
; RV32ZBA-NEXT: ret
1236+
;
1237+
; RV32XANDESPERF-LABEL: select5i64:
1238+
; RV32XANDESPERF: # %bb.0:
1239+
; RV32XANDESPERF-NEXT: nds.lea.w a0, a0, a0
1240+
; RV32XANDESPERF-NEXT: li a1, 0
1241+
; RV32XANDESPERF-NEXT: ret
11881242
%select = select i1 %x, i64 5, i64 0
11891243
ret i64 %select
11901244
}
11911245

11921246
define i64 @select9i64(i1 zeroext %x) {
1193-
; CHECK-LABEL: select9i64:
1194-
; CHECK: # %bb.0:
1195-
; CHECK-NEXT: neg a0, a0
1196-
; CHECK-NEXT: andi a0, a0, 9
1197-
; CHECK-NEXT: li a1, 0
1198-
; CHECK-NEXT: ret
1247+
; RV32I-LABEL: select9i64:
1248+
; RV32I: # %bb.0:
1249+
; RV32I-NEXT: neg a0, a0
1250+
; RV32I-NEXT: andi a0, a0, 9
1251+
; RV32I-NEXT: li a1, 0
1252+
; RV32I-NEXT: ret
1253+
;
1254+
; RV32ZBA-LABEL: select9i64:
1255+
; RV32ZBA: # %bb.0:
1256+
; RV32ZBA-NEXT: sh3add a0, a0, a0
1257+
; RV32ZBA-NEXT: li a1, 0
1258+
; RV32ZBA-NEXT: ret
1259+
;
1260+
; RV32XANDESPERF-LABEL: select9i64:
1261+
; RV32XANDESPERF: # %bb.0:
1262+
; RV32XANDESPERF-NEXT: nds.lea.d a0, a0, a0
1263+
; RV32XANDESPERF-NEXT: li a1, 0
1264+
; RV32XANDESPERF-NEXT: ret
11991265
%select = select i1 %x, i64 9, i64 0
12001266
ret i64 %select
12011267
}

llvm/test/CodeGen/RISCV/rv64zba.ll

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4578,31 +4578,61 @@ define i64 @append_32ones(i64 %x) {
45784578
}
45794579

45804580
define i32 @select3(i1 zeroext %x) {
4581-
; CHECK-LABEL: select3:
4582-
; CHECK: # %bb.0:
4583-
; CHECK-NEXT: neg a0, a0
4584-
; CHECK-NEXT: andi a0, a0, 3
4585-
; CHECK-NEXT: ret
4581+
; RV64I-LABEL: select3:
4582+
; RV64I: # %bb.0:
4583+
; RV64I-NEXT: neg a0, a0
4584+
; RV64I-NEXT: andi a0, a0, 3
4585+
; RV64I-NEXT: ret
4586+
;
4587+
; RV64ZBA-LABEL: select3:
4588+
; RV64ZBA: # %bb.0:
4589+
; RV64ZBA-NEXT: sh1add a0, a0, a0
4590+
; RV64ZBA-NEXT: ret
4591+
;
4592+
; RV64XANDESPERF-LABEL: select3:
4593+
; RV64XANDESPERF: # %bb.0:
4594+
; RV64XANDESPERF-NEXT: nds.lea.h a0, a0, a0
4595+
; RV64XANDESPERF-NEXT: ret
45864596
%select = select i1 %x, i32 3, i32 0
45874597
ret i32 %select
45884598
}
45894599

45904600
define i32 @select5(i1 zeroext %x) {
4591-
; CHECK-LABEL: select5:
4592-
; CHECK: # %bb.0:
4593-
; CHECK-NEXT: neg a0, a0
4594-
; CHECK-NEXT: andi a0, a0, 5
4595-
; CHECK-NEXT: ret
4601+
; RV64I-LABEL: select5:
4602+
; RV64I: # %bb.0:
4603+
; RV64I-NEXT: neg a0, a0
4604+
; RV64I-NEXT: andi a0, a0, 5
4605+
; RV64I-NEXT: ret
4606+
;
4607+
; RV64ZBA-LABEL: select5:
4608+
; RV64ZBA: # %bb.0:
4609+
; RV64ZBA-NEXT: sh2add a0, a0, a0
4610+
; RV64ZBA-NEXT: ret
4611+
;
4612+
; RV64XANDESPERF-LABEL: select5:
4613+
; RV64XANDESPERF: # %bb.0:
4614+
; RV64XANDESPERF-NEXT: nds.lea.w a0, a0, a0
4615+
; RV64XANDESPERF-NEXT: ret
45964616
%select = select i1 %x, i32 5, i32 0
45974617
ret i32 %select
45984618
}
45994619

46004620
define i32 @select9(i1 zeroext %x) {
4601-
; CHECK-LABEL: select9:
4602-
; CHECK: # %bb.0:
4603-
; CHECK-NEXT: neg a0, a0
4604-
; CHECK-NEXT: andi a0, a0, 9
4605-
; CHECK-NEXT: ret
4621+
; RV64I-LABEL: select9:
4622+
; RV64I: # %bb.0:
4623+
; RV64I-NEXT: neg a0, a0
4624+
; RV64I-NEXT: andi a0, a0, 9
4625+
; RV64I-NEXT: ret
4626+
;
4627+
; RV64ZBA-LABEL: select9:
4628+
; RV64ZBA: # %bb.0:
4629+
; RV64ZBA-NEXT: sh3add a0, a0, a0
4630+
; RV64ZBA-NEXT: ret
4631+
;
4632+
; RV64XANDESPERF-LABEL: select9:
4633+
; RV64XANDESPERF: # %bb.0:
4634+
; RV64XANDESPERF-NEXT: nds.lea.d a0, a0, a0
4635+
; RV64XANDESPERF-NEXT: ret
46064636
%select = select i1 %x, i32 9, i32 0
46074637
ret i32 %select
46084638
}

llvm/test/CodeGen/RISCV/xqciac.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -609,14 +609,12 @@ define i32 @select65(i1 zeroext %x) {
609609
;
610610
; RV32IMXQCIAC-LABEL: select65:
611611
; RV32IMXQCIAC: # %bb.0:
612-
; RV32IMXQCIAC-NEXT: neg a0, a0
613-
; RV32IMXQCIAC-NEXT: andi a0, a0, 65
612+
; RV32IMXQCIAC-NEXT: qc.shladd a0, a0, a0, 6
614613
; RV32IMXQCIAC-NEXT: ret
615614
;
616615
; RV32IZBAMXQCIAC-LABEL: select65:
617616
; RV32IZBAMXQCIAC: # %bb.0:
618-
; RV32IZBAMXQCIAC-NEXT: neg a0, a0
619-
; RV32IZBAMXQCIAC-NEXT: andi a0, a0, 65
617+
; RV32IZBAMXQCIAC-NEXT: qc.shladd a0, a0, a0, 6
620618
; RV32IZBAMXQCIAC-NEXT: ret
621619
%select = select i1 %x, i32 65, i32 0
622620
ret i32 %select

0 commit comments

Comments
 (0)