Skip to content

Commit ec2ce34

Browse files
authored
[RISCV] Lower (select c, (1 << X) + 1, 0) -> (shXadd c, c) (llvm#158969)
1 parent 6d5c942 commit ec2ce34

File tree

4 files changed

+225
-4
lines changed

4 files changed

+225
-4
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

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

llvm/test/CodeGen/RISCV/rv32zba.ll

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,3 +1136,132 @@ define i32 @mul_neg8(i32 %a) {
11361136
%c = mul i32 %a, -8
11371137
ret i32 %c
11381138
}
1139+
1140+
define i32 @select3i32(i1 zeroext %x) {
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
1156+
%select = select i1 %x, i32 3, i32 0
1157+
ret i32 %select
1158+
}
1159+
1160+
define i32 @select5i32(i1 zeroext %x) {
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
1176+
%select = select i1 %x, i32 5, i32 0
1177+
ret i32 %select
1178+
}
1179+
1180+
define i32 @select9i32(i1 zeroext %x) {
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
1196+
%select = select i1 %x, i32 9, i32 0
1197+
ret i32 %select
1198+
}
1199+
1200+
define i64 @select3i64(i1 zeroext %x) {
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
1219+
%select = select i1 %x, i64 3, i64 0
1220+
ret i64 %select
1221+
}
1222+
1223+
define i64 @select5i64(i1 zeroext %x) {
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
1242+
%select = select i1 %x, i64 5, i64 0
1243+
ret i64 %select
1244+
}
1245+
1246+
define i64 @select9i64(i1 zeroext %x) {
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
1265+
%select = select i1 %x, i64 9, i64 0
1266+
ret i64 %select
1267+
}

llvm/test/CodeGen/RISCV/rv64zba.ll

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4576,3 +4576,63 @@ define i64 @append_32ones(i64 %x) {
45764576
%o = or i64 %s, 4294967295
45774577
ret i64 %o
45784578
}
4579+
4580+
define i32 @select3(i1 zeroext %x) {
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
4596+
%select = select i1 %x, i32 3, i32 0
4597+
ret i32 %select
4598+
}
4599+
4600+
define i32 @select5(i1 zeroext %x) {
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
4616+
%select = select i1 %x, i32 5, i32 0
4617+
ret i32 %select
4618+
}
4619+
4620+
define i32 @select9(i1 zeroext %x) {
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
4636+
%select = select i1 %x, i32 9, i32 0
4637+
ret i32 %select
4638+
}

llvm/test/CodeGen/RISCV/xqciac.ll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,3 +599,23 @@ define i32 @add_shl_moreOneUse_4(i32 %x) {
599599
%add = add i32 %mul, %or
600600
ret i32 %add
601601
}
602+
603+
define i32 @select65(i1 zeroext %x) {
604+
; RV32IM-LABEL: select65:
605+
; RV32IM: # %bb.0:
606+
; RV32IM-NEXT: neg a0, a0
607+
; RV32IM-NEXT: andi a0, a0, 65
608+
; RV32IM-NEXT: ret
609+
;
610+
; RV32IMXQCIAC-LABEL: select65:
611+
; RV32IMXQCIAC: # %bb.0:
612+
; RV32IMXQCIAC-NEXT: qc.shladd a0, a0, a0, 6
613+
; RV32IMXQCIAC-NEXT: ret
614+
;
615+
; RV32IZBAMXQCIAC-LABEL: select65:
616+
; RV32IZBAMXQCIAC: # %bb.0:
617+
; RV32IZBAMXQCIAC-NEXT: qc.shladd a0, a0, a0, 6
618+
; RV32IZBAMXQCIAC-NEXT: ret
619+
%select = select i1 %x, i32 65, i32 0
620+
ret i32 %select
621+
}

0 commit comments

Comments
 (0)