Index: lib/Target/AMDGPU/AMDGPUISelLowering.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPUISelLowering.cpp +++ lib/Target/AMDGPU/AMDGPUISelLowering.cpp @@ -4067,6 +4067,20 @@ Known.Zero.setHighBits(32 - MaxValBits); break; } + case ISD::INTRINSIC_WO_CHAIN: { + unsigned IID = cast(Op.getOperand(0))->getZExtValue(); + switch (IID) { + case Intrinsic::amdgcn_mbcnt_lo: + case Intrinsic::amdgcn_mbcnt_hi: { + // These return at most the wavefront size - 1. + unsigned Size = Op.getValueType().getSizeInBits(); + Known.Zero.setHighBits(Size- Subtarget->getWavefrontSizeLog2()); + break; + } + default: + break; + } + } } } Index: lib/Target/AMDGPU/AMDGPUSubtarget.h =================================================================== --- lib/Target/AMDGPU/AMDGPUSubtarget.h +++ lib/Target/AMDGPU/AMDGPUSubtarget.h @@ -229,6 +229,10 @@ return WavefrontSize; } + unsigned getWavefrontSizeLog2() const { + return Log2_32(WavefrontSize); + } + int getLocalMemorySize() const { return LocalMemorySize; } Index: test/CodeGen/AMDGPU/llvm.amdgcn.mbcnt.ll =================================================================== --- test/CodeGen/AMDGPU/llvm.amdgcn.mbcnt.ll +++ test/CodeGen/AMDGPU/llvm.amdgcn.mbcnt.ll @@ -14,6 +14,24 @@ ret void } +; GCN-LABEL: {{^}}mbcnt_lo_known_bits: +; GCN: v_mbcnt_lo_u32_b32 +; GCN-NOT: and +define i32 @mbcnt_lo_known_bits(i32 %x, i32 %y) #0 { + %lo = call i32 @llvm.amdgcn.mbcnt.lo(i32 %x, i32 %y) + %mask = and i32 %lo, 63 + ret i32 %mask +} + +; GCN-LABEL: {{^}}mbcnt_hi_known_bits: +; GCN: v_mbcnt_hi_u32_b32 +; GCN-NOT: and +define i32 @mbcnt_hi_known_bits(i32 %x, i32 %y) #0 { + %hi = call i32 @llvm.amdgcn.mbcnt.hi(i32 %x, i32 %y) + %mask = and i32 %hi, 63 + ret i32 %mask +} + declare i32 @llvm.amdgcn.mbcnt.lo(i32, i32) #0 declare i32 @llvm.amdgcn.mbcnt.hi(i32, i32) #0 declare void @llvm.amdgcn.exp.f32(i32, i32, float, float, float, float, i1, i1) #1