diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -918,7 +918,10 @@ 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(Val))) ExtendKind = ISD::ZERO_EXTEND; getCopyToParts(DAG, dl, Val.getValue(Val.getResNo() + Value), &Parts[Part], diff --git a/llvm/test/CodeGen/RISCV/aext-to-sext.ll b/llvm/test/CodeGen/RISCV/aext-to-sext.ll --- a/llvm/test/CodeGen/RISCV/aext-to-sext.ll +++ b/llvm/test/CodeGen/RISCV/aext-to-sext.ll @@ -80,19 +80,25 @@ ; 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