[SelectionDAG][RISCV] Make RegsForValue::getCopyToRegs explicitly zero_extend constants.

ComputePHILiveOutRegInfo assumes that constant incoming values to
Phis will be zero extended if they aren't a legal type. To guarantee
that we should zero_extend rather than any_extend constants.

This fixes a bug for RISCV where any_extend of constants can be
treated as a sign_extend.

Differential Revision: https://reviews.llvm.org/D122053
This commit is contained in:
Craig Topper 2022-03-18 18:33:30 -07:00
parent 268371cf7b
commit 4eb59f0179
2 changed files with 17 additions and 8 deletions

View File

@ -918,7 +918,10 @@ void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG,
CallConv.getValue(), RegVTs[Value])
: RegVTs[Value];
if (ExtendKind == ISD::ANY_EXTEND && TLI.isZExtFree(Val, RegisterVT))
// We need to zero extend constants that are liveout to match assumptions
// in FunctionLoweringInfo::ComputePHILiveOutRegInfo.
if (ExtendKind == ISD::ANY_EXTEND &&
(TLI.isZExtFree(Val, RegisterVT) || isa<ConstantSDNode>(Val)))
ExtendKind = ISD::ZERO_EXTEND;
getCopyToParts(DAG, dl, Val.getValue(Val.getResNo() + Value), &Parts[Part],

View File

@ -80,19 +80,25 @@ bar:
; constants are zero extended for phi incoming values so an AssertZExt is
; created in 'merge' allowing the zext to be removed.
; SelectionDAG::getNode treats any_extend of i32 constants as sext for RISCV.
; The code that creates phi incoming values in the predecessors creates an
; any_extend for the constants which then gets treated as a sext by getNode.
; This means the zext was not safe to remove.
; This code used to miscompile because the code that creates phi incoming values
; in the predecessors created any_extend for the constants which then gets
; treated as a sext by getNode. This made the removal of the zext incorrect.
; SelectionDAGBuilder now creates a zero_extend instead of an any_extend to
; match the assumption.
; FIXME: RISCV would prefer constant inputs to phis to be sign extended.
define i64 @miscompile(i32 %c) {
; RV64I-LABEL: miscompile:
; RV64I: # %bb.0:
; RV64I-NEXT: sext.w a1, a0
; RV64I-NEXT: sext.w a0, a0
; RV64I-NEXT: beqz a0, .LBB2_2
; RV64I-NEXT: # %bb.1:
; RV64I-NEXT: li a0, -1
; RV64I-NEXT: beqz a1, .LBB2_2
; RV64I-NEXT: # %bb.1: # %merge
; RV64I-NEXT: srli a0, a0, 32
; RV64I-NEXT: ret
; RV64I-NEXT: .LBB2_2: # %iffalse
; RV64I-NEXT: li a0, -2
; RV64I-NEXT: li a0, 1
; RV64I-NEXT: slli a0, a0, 32
; RV64I-NEXT: addi a0, a0, -2
; RV64I-NEXT: ret
%a = icmp ne i32 %c, 0
br i1 %a, label %iftrue, label %iffalse