Given the pointer operation: long delta = smaller & (read - first); This gets lowered as (-fdump-tree-original) long delta = (long) smaller & (read - first) / 8; Instead of... long delta = (long) smaller & (read - first) /[ex] 8; Switching will likely give some marginal gains on performance.
--- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -620,6 +620,18 @@ public: break; case TOKdiv: + /* Determine if the div expression is a lowered pointer diff operation. + The front-end rewrites `(p1 - p2)' into `(p1 - p2) / stride'. */ + if (MinExp *me = e->e1->isMinExp ()) + { + if (me->e1->type->ty == Tpointer && me->e2->type->ty == Tpointer + && e->e2->op == TOKint64) + { + code = EXACT_DIV_EXPR; + break; + } + } + code = e->e1->type->isintegral () ? TRUNC_DIV_EXPR : RDIV_EXPR; break;
The master branch has been updated by Iain Buclaw <ibuclaw@gcc.gnu.org>: https://gcc.gnu.org/g:3a3fda119036f46bfa70e06e7c69e04e78040079 commit r11-2536-g3a3fda119036f46bfa70e06e7c69e04e78040079 Author: Iain Buclaw <ibuclaw@gdcproject.org> Date: Mon Aug 3 22:35:38 2020 +0200 d: Fix PR96429: Pointer subtraction uses TRUNC_DIV_EXPR gcc/d/ChangeLog: PR d/96429 * expr.cc (ExprVisitor::visit (BinExp*)): Use EXACT_DIV_EXPR for pointer diff expressions. gcc/testsuite/ChangeLog: PR d/96429 * gdc.dg/pr96429.d: New test.
Fixed.