diff --git a/llvm/test/CodeGen/RISCV/rv64zba.ll b/llvm/test/CodeGen/RISCV/rv64zba.ll --- a/llvm/test/CodeGen/RISCV/rv64zba.ll +++ b/llvm/test/CodeGen/RISCV/rv64zba.ll @@ -371,6 +371,49 @@ ret i64 %5 } +; Type legalization inserts a sext_inreg after the first add. That add will be +; selected as sh2add which does not sign extend. SimplifyDemandedBits is unable +; to remove the sext_inreg because it has multiple uses. The ashr will use the +; sext_inreg to become sraiw. This leaves the sext_inreg only used by the shl. +; If the shl is selected as sllw, we don't need the sext_inreg. +; FIXME: We should not emit a sext.w. +define i64 @sh2add_extra_sext(i32 %x, i32 %y, i32 %z) { +; RV64I-LABEL: sh2add_extra_sext: +; RV64I: # %bb.0: +; RV64I-NEXT: slliw a0, a0, 2 +; RV64I-NEXT: addw a0, a0, a1 +; RV64I-NEXT: sllw a1, a2, a0 +; RV64I-NEXT: sraiw a0, a0, 2 +; RV64I-NEXT: mul a0, a1, a0 +; RV64I-NEXT: ret +; +; RV64B-LABEL: sh2add_extra_sext: +; RV64B: # %bb.0: +; RV64B-NEXT: sh2add a0, a0, a1 +; RV64B-NEXT: sext.w a1, a0 +; RV64B-NEXT: sllw a1, a2, a1 +; RV64B-NEXT: sraiw a0, a0, 2 +; RV64B-NEXT: mul a0, a1, a0 +; RV64B-NEXT: ret +; +; RV64ZBA-LABEL: sh2add_extra_sext: +; RV64ZBA: # %bb.0: +; RV64ZBA-NEXT: sh2add a0, a0, a1 +; RV64ZBA-NEXT: sext.w a1, a0 +; RV64ZBA-NEXT: sllw a1, a2, a1 +; RV64ZBA-NEXT: sraiw a0, a0, 2 +; RV64ZBA-NEXT: mul a0, a1, a0 +; RV64ZBA-NEXT: ret + %a = shl i32 %x, 2 + %b = add i32 %a, %y + %c = shl i32 %z, %b + %d = ashr i32 %b, 2 + %e = sext i32 %c to i64 + %f = sext i32 %d to i64 + %g = mul i64 %e, %f + ret i64 %g +} + define i64 @addmul6(i64 %a, i64 %b) { ; RV64I-LABEL: addmul6: ; RV64I: # %bb.0: