Optimize 2 ** X to 1 << X if base is signed
This commit is contained in:
parent
f535a73ea7
commit
4f59b4acfe
|
@ -158,6 +158,7 @@ Martin Schmidt
|
||||||
Martin Stadler
|
Martin Stadler
|
||||||
Mateusz Gancarz
|
Mateusz Gancarz
|
||||||
Matthew Ballance
|
Matthew Ballance
|
||||||
|
Max Wipfli
|
||||||
Michael Bikovitsky
|
Michael Bikovitsky
|
||||||
Michael Killough
|
Michael Killough
|
||||||
Michal Czyz
|
Michal Czyz
|
||||||
|
|
|
@ -1267,8 +1267,12 @@ class ConstVisitor final : public VNVisitor {
|
||||||
&& nodep->lhsp()->isPure());
|
&& nodep->lhsp()->isPure());
|
||||||
}
|
}
|
||||||
bool operandIsTwo(const AstNode* nodep) {
|
bool operandIsTwo(const AstNode* nodep) {
|
||||||
return (VN_IS(nodep, Const) && !VN_AS(nodep, Const)->num().isFourState()
|
const AstConst* const constp = VN_CAST(nodep, Const);
|
||||||
&& nodep->width() <= VL_QUADSIZE && VN_AS(nodep, Const)->toUQuad() == 2);
|
if (!constp) return false; // not constant
|
||||||
|
if (constp->num().isFourState()) return false; // four-state
|
||||||
|
if (nodep->width() > VL_QUADSIZE) return false; // too wide
|
||||||
|
if (nodep->isSigned() && constp->num().isNegative()) return false; // signed and negative
|
||||||
|
return constp->toUQuad() == 2;
|
||||||
}
|
}
|
||||||
bool operandIsTwostate(const AstNode* nodep) {
|
bool operandIsTwostate(const AstNode* nodep) {
|
||||||
return (VN_IS(nodep, Const) && !VN_AS(nodep, Const)->num().isFourState());
|
return (VN_IS(nodep, Const) && !VN_AS(nodep, Const)->num().isFourState());
|
||||||
|
@ -3550,6 +3554,7 @@ class ConstVisitor final : public VNVisitor {
|
||||||
TREEOP ("AstDiv {$lhsp, operandIsPowTwo($rhsp)}", "replaceDivShift(nodep)"); // a/2^n -> a>>n
|
TREEOP ("AstDiv {$lhsp, operandIsPowTwo($rhsp)}", "replaceDivShift(nodep)"); // a/2^n -> a>>n
|
||||||
TREEOP ("AstModDiv{$lhsp, operandIsPowTwo($rhsp)}", "replaceModAnd(nodep)"); // a % 2^n -> a&(2^n-1)
|
TREEOP ("AstModDiv{$lhsp, operandIsPowTwo($rhsp)}", "replaceModAnd(nodep)"); // a % 2^n -> a&(2^n-1)
|
||||||
TREEOP ("AstPow {operandIsTwo($lhsp), !$rhsp.isZero}", "replacePowShift(nodep)"); // 2**a == 1<<a
|
TREEOP ("AstPow {operandIsTwo($lhsp), !$rhsp.isZero}", "replacePowShift(nodep)"); // 2**a == 1<<a
|
||||||
|
TREEOP ("AstPowSU {operandIsTwo($lhsp), !$rhsp.isZero}", "replacePowShift(nodep)"); // 2**a == 1<<a
|
||||||
TREEOP ("AstSub {$lhsp.castAdd, operandSubAdd(nodep)}", "AstAdd{AstSub{$lhsp->castAdd()->lhsp(),$rhsp}, $lhsp->castAdd()->rhsp()}"); // ((a+x)-y) -> (a+(x-y))
|
TREEOP ("AstSub {$lhsp.castAdd, operandSubAdd(nodep)}", "AstAdd{AstSub{$lhsp->castAdd()->lhsp(),$rhsp}, $lhsp->castAdd()->rhsp()}"); // ((a+x)-y) -> (a+(x-y))
|
||||||
TREEOPC("AstAnd {$lhsp.isOne, matchRedundantClean(nodep)}", "DONE") // 1 & (a == b) -> (IData)(a == b)
|
TREEOPC("AstAnd {$lhsp.isOne, matchRedundantClean(nodep)}", "DONE") // 1 & (a == b) -> (IData)(a == b)
|
||||||
// Trinary ops
|
// Trinary ops
|
||||||
|
|
|
@ -37,7 +37,8 @@ module t (/*AUTOARG*/
|
||||||
wire signed [66:0] bsw = b[66:0];
|
wire signed [66:0] bsw = b[66:0];
|
||||||
|
|
||||||
// verilator lint_off WIDTH
|
// verilator lint_off WIDTH
|
||||||
wire [66:0] shifted = 2 ** b[20:0];
|
wire [66:0] shifted = 32'd2 ** b[20:0];
|
||||||
|
wire [66:0] shifted_signed = 32'sd2 ** b[20:0];
|
||||||
|
|
||||||
wire [15:0] uiii = aui ** bui;
|
wire [15:0] uiii = aui ** bui;
|
||||||
wire [15:0] uiiq = aui ** buq;
|
wire [15:0] uiiq = aui ** buq;
|
||||||
|
@ -358,5 +359,6 @@ module t (/*AUTOARG*/
|
||||||
32'd09: `checkh(shifted, 67'h0000000000000000);
|
32'd09: `checkh(shifted, 67'h0000000000000000);
|
||||||
default: ;
|
default: ;
|
||||||
endcase
|
endcase
|
||||||
|
`checkh(shifted_signed, shifted);
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
|
Loading…
Reference in New Issue