diff --git a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td --- a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td +++ b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td @@ -731,16 +731,16 @@ return v.isIntN(16); }]>; -def Int5Const : PatLeaf<(imm), [{ - // Check if 0 <= v < 32; only then will the result of (x << v) be an int32. +def IntConst_0_30 : PatLeaf<(imm), [{ + // Check if 0 <= v < 31; only then will the result of (x << v) be an int32. const APInt &v = N->getAPIntValue(); - return v.sge(0) && v.slt(32); + return v.sge(0) && v.slt(31); }]>; -def Int4Const : PatLeaf<(imm), [{ - // Check if 0 <= v < 16; only then will the result of (x << v) be an int16. +def IntConst_0_14 : PatLeaf<(imm), [{ + // Check if 0 <= v < 15; only then will the result of (x << v) be an int16. const APInt &v = N->getAPIntValue(); - return v.sge(0) && v.slt(16); + return v.sge(0) && v.slt(15); }]>; def SHL2MUL32 : SDNodeXForm; // Convert "sign/zero-extend, then shift left by an immediate" to mul.wide. -def : Pat<(shl (sext Int32Regs:$a), (i32 Int5Const:$b)), +def : Pat<(shl (sext Int32Regs:$a), (i32 IntConst_0_30:$b)), (MULWIDES64Imm Int32Regs:$a, (SHL2MUL32 node:$b))>, Requires<[doMulWide]>; -def : Pat<(shl (zext Int32Regs:$a), (i32 Int5Const:$b)), +def : Pat<(shl (zext Int32Regs:$a), (i32 IntConst_0_30:$b)), (MULWIDEU64Imm Int32Regs:$a, (SHL2MUL32 node:$b))>, Requires<[doMulWide]>; -def : Pat<(shl (sext Int16Regs:$a), (i16 Int4Const:$b)), +def : Pat<(shl (sext Int16Regs:$a), (i16 IntConst_0_14:$b)), (MULWIDES32Imm Int16Regs:$a, (SHL2MUL16 node:$b))>, Requires<[doMulWide]>; -def : Pat<(shl (zext Int16Regs:$a), (i16 Int4Const:$b)), +def : Pat<(shl (zext Int16Regs:$a), (i16 IntConst_0_14:$b)), (MULWIDEU32Imm Int16Regs:$a, (SHL2MUL16 node:$b))>, Requires<[doMulWide]>; diff --git a/llvm/test/CodeGen/NVPTX/mulwide.ll b/llvm/test/CodeGen/NVPTX/mulwide.ll --- a/llvm/test/CodeGen/NVPTX/mulwide.ll +++ b/llvm/test/CodeGen/NVPTX/mulwide.ll @@ -90,3 +90,23 @@ %val2 = mul i64 %val0, %val1 ret i64 %val2 } + +; OPT-LABEL: @shl30 +; NOOPT-LABEL: @shl30 +define i64 @shl30(i32 %a) { +; OPT: mul.wide +; NOOPT: shl.b64 + %conv = sext i32 %a to i64 + %shl = shl i64 %conv, 30 + ret i64 %shl +} + +; OPT-LABEL: @shl31 +; NOOPT-LABEL: @shl31 +define i64 @shl31(i32 %a) { +; OPT-NOT: mul.wide +; NOOPT-NOT: mul.wide + %conv = sext i32 %a to i64 + %shl = shl i64 %conv, 31 + ret i64 %shl +}