@@ -2329,20 +2329,45 @@ static ref<Expr> AShrExpr_create(const ref<Expr> &l, const ref<Expr> &r) {
23292329 }
23302330}
23312331
2332+ template <typename T> static bool isDiv () {
2333+ return T::kind == Expr::Kind::SDiv || T::kind == Expr::Kind::UDiv ||
2334+ T::kind == Expr::Kind::FDiv;
2335+ }
2336+
2337+ // / Heuristic.
2338+ // / Attempts to sift up select expression during creation.
2339+ template <typename T>
2340+ static ref<Expr> tryCreateWithSiftUpSelectExpr (const ref<Expr> &l,
2341+ const ref<Expr> &r,
2342+ bool skipInnerSelect = false ) {
2343+ if (isDiv<T>()) {
2344+ return nullptr ;
2345+ }
2346+
2347+ if (ref<SelectExpr> sel = dyn_cast<SelectExpr>(l)) {
2348+ if (isa<ConstantExpr>(sel->trueExpr ) &&
2349+ (!skipInnerSelect || !isa<SelectExpr>(r))) {
2350+ return SelectExpr::create (sel->cond , T::create (sel->trueExpr , r),
2351+ T::create (sel->falseExpr , r));
2352+ }
2353+ }
2354+ if (ref<SelectExpr> ser = dyn_cast<SelectExpr>(r)) {
2355+ if (isa<ConstantExpr>(ser->trueExpr ) &&
2356+ (!skipInnerSelect || !isa<SelectExpr>(l))) {
2357+ return SelectExpr::create (ser->cond , T::create (l, ser->trueExpr ),
2358+ T::create (l, ser->falseExpr ));
2359+ }
2360+ }
2361+
2362+ return nullptr ;
2363+ }
2364+
23322365#define BCREATE_R (_e_op, _op, partialL, partialR, pointerL, pointerR ) \
23332366 ref<Expr> _e_op ::create (const ref<Expr> &l, const ref<Expr> &r) { \
23342367 assert (l->getWidth () == r->getWidth () && " type mismatch" ); \
2335- if (SelectExpr *sel = dyn_cast<SelectExpr>(l)) { \
2336- if (isa<ConstantExpr>(sel->trueExpr )) { \
2337- return SelectExpr::create (sel->cond , _e_op::create (sel->trueExpr , r), \
2338- _e_op::create (sel->falseExpr , r)); \
2339- } \
2340- } \
2341- if (SelectExpr *ser = dyn_cast<SelectExpr>(r)) { \
2342- if (isa<ConstantExpr>(ser->trueExpr )) { \
2343- return SelectExpr::create (ser->cond , _e_op::create (l, ser->trueExpr ), \
2344- _e_op::create (l, ser->falseExpr )); \
2345- } \
2368+ if (auto withSiftUpSelectExpr = \
2369+ tryCreateWithSiftUpSelectExpr<_e_op>(l, r)) { \
2370+ return withSiftUpSelectExpr; \
23462371 } \
23472372 if (PointerExpr *pl = dyn_cast<PointerExpr>(l)) { \
23482373 if (PointerExpr *pr = dyn_cast<PointerExpr>(r)) \
@@ -2364,17 +2389,9 @@ static ref<Expr> AShrExpr_create(const ref<Expr> &l, const ref<Expr> &r) {
23642389#define BCREATE_R_C (_e_op, _op, partialL, partialR, pointerL, pointerR ) \
23652390 ref<Expr> _e_op ::create (const ref<Expr> &l, const ref<Expr> &r) { \
23662391 assert (l->getWidth () == r->getWidth () && " type mismatch" ); \
2367- if (SelectExpr *sel = dyn_cast<SelectExpr>(l)) { \
2368- if (isa<ConstantExpr>(sel->trueExpr )) { \
2369- return SelectExpr::create (sel->cond , _e_op::create (sel->trueExpr , r), \
2370- _e_op::create (sel->falseExpr , r)); \
2371- } \
2372- } \
2373- if (SelectExpr *ser = dyn_cast<SelectExpr>(r)) { \
2374- if (isa<ConstantExpr>(ser->trueExpr )) { \
2375- return SelectExpr::create (ser->cond , _e_op::create (l, ser->trueExpr ), \
2376- _e_op::create (l, ser->falseExpr )); \
2377- } \
2392+ if (auto withSiftUpSelectExpr = \
2393+ tryCreateWithSiftUpSelectExpr<_e_op>(l, r)) { \
2394+ return withSiftUpSelectExpr; \
23782395 } \
23792396 if (PointerExpr *pl = dyn_cast<PointerExpr>(l)) { \
23802397 if (PointerExpr *pr = dyn_cast<PointerExpr>(r)) \
@@ -2409,17 +2426,9 @@ static ref<Expr> AShrExpr_create(const ref<Expr> &l, const ref<Expr> &r) {
24092426#define BCREATE (_e_op, _op ) \
24102427 ref<Expr> _e_op ::create (const ref<Expr> &l, const ref<Expr> &r) { \
24112428 assert (l->getWidth () == r->getWidth () && " type mismatch" ); \
2412- if (SelectExpr *sel = dyn_cast<SelectExpr>(l)) { \
2413- if (isa<ConstantExpr>(sel->trueExpr )) { \
2414- return SelectExpr::create (sel->cond , _e_op::create (sel->trueExpr , r), \
2415- _e_op::create (sel->falseExpr , r)); \
2416- } \
2417- } \
2418- if (SelectExpr *ser = dyn_cast<SelectExpr>(r)) { \
2419- if (isa<ConstantExpr>(ser->trueExpr )) { \
2420- return SelectExpr::create (ser->cond , _e_op::create (l, ser->trueExpr ), \
2421- _e_op::create (l, ser->falseExpr )); \
2422- } \
2429+ if (auto withSiftUpSelectExpr = \
2430+ tryCreateWithSiftUpSelectExpr<_e_op>(l, r)) { \
2431+ return withSiftUpSelectExpr; \
24232432 } \
24242433 if (PointerExpr *pl = dyn_cast<PointerExpr>(l)) { \
24252434 if (PointerExpr *pr = dyn_cast<PointerExpr>(r)) \
@@ -2457,17 +2466,9 @@ BCREATE(AShrExpr, AShr)
24572466#define CMPCREATE (_e_op, _op ) \
24582467 ref<Expr> _e_op ::create (const ref<Expr> &l, const ref<Expr> &r) { \
24592468 assert (l->getWidth () == r->getWidth () && " type mismatch" ); \
2460- if (SelectExpr *sel = dyn_cast<SelectExpr>(l)) { \
2461- if (isa<ConstantExpr>(sel->trueExpr ) && !isa<SelectExpr>(r)) { \
2462- return SelectExpr::create (sel->cond , _e_op::create (sel->trueExpr , r), \
2463- _e_op::create (sel->falseExpr , r)); \
2464- } \
2465- } \
2466- if (SelectExpr *ser = dyn_cast<SelectExpr>(r)) { \
2467- if (isa<ConstantExpr>(ser->trueExpr ) && !isa<SelectExpr>(l)) { \
2468- return SelectExpr::create (ser->cond , _e_op::create (l, ser->trueExpr ), \
2469- _e_op::create (l, ser->falseExpr )); \
2470- } \
2469+ if (auto withSiftUpSelectExpr = \
2470+ tryCreateWithSiftUpSelectExpr<_e_op>(l, r, true )) { \
2471+ return withSiftUpSelectExpr; \
24712472 } \
24722473 if (PointerExpr *pl = dyn_cast<PointerExpr>(l)) { \
24732474 if (PointerExpr *pr = dyn_cast<PointerExpr>(r)) \
@@ -2485,17 +2486,9 @@ BCREATE(AShrExpr, AShr)
24852486#define CMPCREATE_T (_e_op, _op, _reflexive_e_op, partialL, partialR ) \
24862487 ref<Expr> _e_op ::create (const ref<Expr> &l, const ref<Expr> &r) { \
24872488 assert (l->getWidth () == r->getWidth () && " type mismatch" ); \
2488- if (SelectExpr *sel = dyn_cast<SelectExpr>(l)) { \
2489- if (isa<ConstantExpr>(sel->trueExpr ) && !isa<SelectExpr>(r)) { \
2490- return SelectExpr::create (sel->cond , _e_op::create (sel->trueExpr , r), \
2491- _e_op::create (sel->falseExpr , r)); \
2492- } \
2493- } \
2494- if (SelectExpr *ser = dyn_cast<SelectExpr>(r)) { \
2495- if (isa<ConstantExpr>(ser->trueExpr ) && !isa<SelectExpr>(l)) { \
2496- return SelectExpr::create (ser->cond , _e_op::create (l, ser->trueExpr ), \
2497- _e_op::create (l, ser->falseExpr )); \
2498- } \
2489+ if (auto withSiftUpSelectExpr = \
2490+ tryCreateWithSiftUpSelectExpr<_e_op>(l, r, true )) { \
2491+ return withSiftUpSelectExpr; \
24992492 } \
25002493 if (PointerExpr *pl = dyn_cast<PointerExpr>(l)) { \
25012494 if (PointerExpr *pr = dyn_cast<PointerExpr>(r)) \
0 commit comments