Index: llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp =================================================================== --- llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp +++ llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp @@ -3293,7 +3293,7 @@ } // How many bits are in our mask? - uint64_t NumBits = llvm::countr_one(MaskVal); + int64_t NumBits = countTrailingOnes(MaskVal); Len = CurDAG->getTargetConstant(NumBits, DL, MVT::i32); if (LHS.getOpcode() == ISD::SRL || LHS.getOpcode() == ISD::SRA) { @@ -3305,7 +3305,7 @@ uint64_t StartVal = StartConst->getZExtValue(); // How many "good" bits do we have left? "good" is defined here as bits // that exist in the original value, not shifted in. - uint64_t GoodBits = Start.getValueSizeInBits() - StartVal; + int64_t GoodBits = Start.getValueSizeInBits() - StartVal; if (NumBits > GoodBits) { // Do not handle the case where bits have been shifted in. In theory // we could handle this, but the cost is likely higher than just Index: llvm/test/CodeGen/NVPTX/bfe.ll =================================================================== --- llvm/test/CodeGen/NVPTX/bfe.ll +++ llvm/test/CodeGen/NVPTX/bfe.ll @@ -31,3 +31,37 @@ %val1 = and i32 %val0, 7 ret i32 %val1 } + +; CHECK-LABEL: no_bfe_on_32bit_overflow +define i32 @no_bfe_on_32bit_overflow(i32 %a) { +; CHECK-NOT: bfe.u32 %r{{[0-9]+}}, %r{{[0-9]+}}, 31, 4 + %val0 = ashr i32 %a, 31 + %val1 = and i32 %val0, 15 + ret i32 %val1 +} + +; CHECK-LABEL: no_bfe_on_32bit_overflow_shr_and_pair +define i32 @no_bfe_on_32bit_overflow_shr_and_pair(i32 %a) { +; CHECK: shr.s32 %r{{[0-9]+}}, %r{{[0-9]+}}, 31 +; CHECK: and.b32 %r{{[0-9]+}}, %r{{[0-9]+}}, 15 + %val0 = ashr i32 %a, 31 + %val1 = and i32 %val0, 15 + ret i32 %val1 +} + +; CHECK-LABEL: no_bfe_on_64bit_overflow +define i64 @no_bfe_on_64bit_overflow(i64 %a) { +; CHECK-NOT: bfe.u64 %rd{{[0-9]+}}, %rd{{[0-9]+}}, 63, 3 + %val0 = ashr i64 %a, 63 + %val1 = and i64 %val0, 7 + ret i64 %val1 +} + +; CHECK-LABEL: no_bfe_on_64bit_overflow_shr_and_pair +define i64 @no_bfe_on_64bit_overflow_shr_and_pair(i64 %a) { +; CHECK: shr.s64 %rd{{[0-9]+}}, %rd{{[0-9]+}}, 63 +; CHECK: and.b64 %rd{{[0-9]+}}, %rd{{[0-9]+}}, 7 + %val0 = ashr i64 %a, 63 + %val1 = and i64 %val0, 7 + ret i64 %val1 +}