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<imm, [{
}]>;
// 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]>;
%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
+}