Skip to content

Commit 83c560b

Browse files
authored
[SDAG] Prefer forming sign_extend for zext nneg per target preference (#70725)
Builds on #67982 which recently introduced the nneg flag on a zext instruction. Note that this change is the first point where the flag is being used for an optimization, and thus may expose latent miscompiles. We've recently taught both CVP and InstCombine to infer the flag when forming zext, but nothing else is using the flag just yet.
1 parent f82bee1 commit 83c560b

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3524,8 +3524,20 @@ void SelectionDAGBuilder::visitZExt(const User &I) {
35243524
// ZExt cannot be a no-op cast because sizeof(src) < sizeof(dest).
35253525
// ZExt also can't be a cast to bool for same reason. So, nothing much to do
35263526
SDValue N = getValue(I.getOperand(0));
3527-
EVT DestVT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(),
3528-
I.getType());
3527+
auto &TLI = DAG.getTargetLoweringInfo();
3528+
EVT DestVT = TLI.getValueType(DAG.getDataLayout(), I.getType());
3529+
3530+
// Since we don't yet have a representation of zext nneg in SDAG or MI,
3531+
// eagerly use the information to canonicalize towards sign_extend if
3532+
// that is the target's preference. TODO: Add nneg support to the
3533+
// SDAG and MI representations.
3534+
if (auto *PNI = dyn_cast<PossiblyNonNegInst>(&I);
3535+
PNI && PNI->hasNonNeg() &&
3536+
TLI.isSExtCheaperThanZExt(N.getValueType(), DestVT)) {
3537+
setValue(&I, DAG.getNode(ISD::SIGN_EXTEND, getCurSDLoc(), DestVT, N));
3538+
return;
3539+
}
3540+
35293541
setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, getCurSDLoc(), DestVT, N));
35303542
}
35313543

llvm/test/CodeGen/RISCV/sext-zext-trunc.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -501,8 +501,7 @@ define i64 @zext_nneg_i32_to_i64(i32 %a) nounwind {
501501
;
502502
; RV64-LABEL: zext_nneg_i32_to_i64:
503503
; RV64: # %bb.0:
504-
; RV64-NEXT: slli a0, a0, 32
505-
; RV64-NEXT: srli a0, a0, 32
504+
; RV64-NEXT: sext.w a0, a0
506505
; RV64-NEXT: ret
507506
%1 = zext nneg i32 %a to i64
508507
ret i64 %1

0 commit comments

Comments
 (0)