Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -46,6 +46,7 @@ #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/IR/Constant.h" +#include "llvm/IR/ConstantRange.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DebugInfoMetadata.h" @@ -4406,6 +4407,34 @@ assert(Tmp <= VTBits && "Failed to determine minimum sign bits"); return Tmp; } + case ISD::LOAD: { + LoadSDNode *LD = cast(Op); + if (const MDNode *Ranges = LD->getRanges()) { + if (DemandedElts != 1) + break; + + ConstantRange CR = getConstantRangeFromMetadata(*Ranges); + if (VTBits > CR.getBitWidth()) { + switch (LD->getExtensionType()) { + case ISD::SEXTLOAD: + CR = CR.signExtend(VTBits); + break; + case ISD::ZEXTLOAD: + CR = CR.zeroExtend(VTBits); + break; + default: + break; + } + } + + if (VTBits != CR.getBitWidth()) + break; + return std::min(CR.getSignedMin().getNumSignBits(), + CR.getSignedMax().getNumSignBits()); + } + + break; + } case ISD::ATOMIC_CMP_SWAP: case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS: case ISD::ATOMIC_SWAP: Index: llvm/test/CodeGen/AMDGPU/load-range-metadata-sign-bits.ll =================================================================== --- llvm/test/CodeGen/AMDGPU/load-range-metadata-sign-bits.ll +++ llvm/test/CodeGen/AMDGPU/load-range-metadata-sign-bits.ll @@ -7,7 +7,6 @@ ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) ; GCN-NEXT: global_load_dword v0, v[0:1], off glc ; GCN-NEXT: s_waitcnt vmcnt(0) -; GCN-NEXT: v_bfe_i32 v0, v0, 0, 8 ; GCN-NEXT: s_setpc_b64 s[30:31] %val = load volatile i32, ptr addrspace(1) %ptr, align 4, !range !0 ; [-127, 128) %shl = shl i32 %val, 24 @@ -61,11 +60,8 @@ ; GCN-LABEL: range_metadata_sextload_i8_signed_range_i4_i32: ; GCN: ; %bb.0: ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) -; GCN-NEXT: global_load_ubyte v0, v[0:1], off glc +; GCN-NEXT: global_load_sbyte v0, v[0:1], off glc ; GCN-NEXT: s_waitcnt vmcnt(0) -; GCN-NEXT: v_lshlrev_b16_e32 v0, 11, v0 -; GCN-NEXT: v_ashrrev_i16_e32 v0, 11, v0 -; GCN-NEXT: v_bfe_i32 v0, v0, 0, 16 ; GCN-NEXT: s_setpc_b64 s[30:31] %load = load volatile i8, ptr addrspace(1) %ptr, align 1, !range !4 %shl = shl i8 %load, 3 @@ -94,7 +90,6 @@ ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) ; GCN-NEXT: global_load_dword v0, v[0:1], off glc ; GCN-NEXT: s_waitcnt vmcnt(0) -; GCN-NEXT: v_bfe_i32 v0, v0, 0, 1 ; GCN-NEXT: s_setpc_b64 s[30:31] %val = load volatile i32, ptr addrspace(1) %ptr, align 4, !range !6 %shl = shl i32 %val, 31 @@ -123,8 +118,6 @@ ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) ; GCN-NEXT: global_load_dwordx2 v[0:1], v[0:1], off glc ; GCN-NEXT: s_waitcnt vmcnt(0) -; GCN-NEXT: v_lshlrev_b64 v[0:1], 31, v[0:1] -; GCN-NEXT: v_ashrrev_i64 v[0:1], 31, v[0:1] ; GCN-NEXT: s_setpc_b64 s[30:31] %val = load volatile i64, ptr addrspace(1) %ptr, align 4, !range !7 %shl = shl i64 %val, 31 @@ -138,8 +131,6 @@ ; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) ; GCN-NEXT: global_load_dwordx2 v[0:1], v[0:1], off glc ; GCN-NEXT: s_waitcnt vmcnt(0) -; GCN-NEXT: v_lshlrev_b64 v[0:1], 30, v[0:1] -; GCN-NEXT: v_ashrrev_i64 v[0:1], 30, v[0:1] ; GCN-NEXT: s_setpc_b64 s[30:31] %val = load volatile i64, ptr addrspace(1) %ptr, align 4, !range !8 %shl = shl i64 %val, 30