diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp @@ -4626,11 +4626,12 @@ RHSKnown = RHSKnown.trunc(24); if (Opc == AMDGPUISD::MUL_I24) { - unsigned LHSValBits = 24 - LHSKnown.countMinSignBits(); - unsigned RHSValBits = 24 - RHSKnown.countMinSignBits(); - unsigned MaxValBits = std::min(LHSValBits + RHSValBits, 32u); - if (MaxValBits >= 32) + unsigned LHSValBits = LHSKnown.countMaxSignificantBits(); + unsigned RHSValBits = RHSKnown.countMaxSignificantBits(); + unsigned MaxValBits = LHSValBits + RHSValBits; + if (MaxValBits > 32) break; + unsigned SignBits = 32 - MaxValBits + 1; bool LHSNegative = LHSKnown.isNegative(); bool LHSNonNegative = LHSKnown.isNonNegative(); bool LHSPositive = LHSKnown.isStrictlyPositive(); @@ -4639,16 +4640,16 @@ bool RHSPositive = RHSKnown.isStrictlyPositive(); if ((LHSNonNegative && RHSNonNegative) || (LHSNegative && RHSNegative)) - Known.Zero.setHighBits(32 - MaxValBits); + Known.Zero.setHighBits(SignBits); else if ((LHSNegative && RHSPositive) || (LHSPositive && RHSNegative)) - Known.One.setHighBits(32 - MaxValBits); + Known.One.setHighBits(SignBits); } else { - unsigned LHSValBits = 24 - LHSKnown.countMinLeadingZeros(); - unsigned RHSValBits = 24 - RHSKnown.countMinLeadingZeros(); - unsigned MaxValBits = std::min(LHSValBits + RHSValBits, 32u); + unsigned LHSValBits = LHSKnown.countMaxActiveBits(); + unsigned RHSValBits = RHSKnown.countMaxActiveBits(); + unsigned MaxValBits = LHSValBits + RHSValBits; if (MaxValBits >= 32) break; - Known.Zero.setHighBits(32 - MaxValBits); + Known.Zero.setBitsFrom(MaxValBits); } break; } diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-mul24-knownbits.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-mul24-knownbits.ll --- a/llvm/test/CodeGen/AMDGPU/amdgpu-mul24-knownbits.ll +++ b/llvm/test/CodeGen/AMDGPU/amdgpu-mul24-knownbits.ll @@ -33,7 +33,11 @@ ; GCN-LABEL: f: ; GCN: ; %bb.0: ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) -; GCN-NEXT: v_mov_b32_e32 v0, 0 +; GCN-NEXT: s_mov_b32 s4, 0xffff80 +; GCN-NEXT: v_or_b32_e32 v0, s4, v0 +; GCN-NEXT: v_or_b32_e32 v1, s4, v1 +; GCN-NEXT: v_mul_i32_i24_e32 v0, v0, v1 +; GCN-NEXT: v_lshrrev_b32_e32 v0, 14, v0 ; GCN-NEXT: s_setpc_b64 s[30:31] %xx = or i32 %x, -128 ; 0xffffff80 %yy = or i32 %y, -128 ; 0xffffff80