question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Recognize compiler integer division patterns with magic constants

See original GitHub issue

Using http://flaviojslab.blogspot.com/2008/02/integer-division.html as (unverified and maybe incomplete) reference, we can create the following mult.c sample:

unsigned int f_0x069C16BD_s0(unsigned int x) { return x * 665/25756; }
unsigned int f_0x10624DD3_s4(unsigned int x) { return x * 1/250; }
unsigned int f_0x10624DD3_s5(unsigned int x) { return x * 1/500; }
unsigned int f_0x10624DD3_s6(unsigned int x) { return x * 1/1000; }
unsigned int f_0x2AAAAAAB_s0(unsigned int x) { return x * 1/6; }
unsigned int f_0x30C30C31_s3(unsigned int x) { return x * 1/42; }
unsigned int f_0x38E38E39_s1(unsigned int x) { return x * 1/9; }
unsigned int f_0x4EC4EC4F_s3(unsigned int x) { return x * 1/26; }
unsigned int f_0x51EB851F_s5(unsigned int x) { return x * 1/100; }
unsigned int f_0x55555556_s0(unsigned int x) { return x * 1/3; }
unsigned int f_0x66666667_s1(unsigned int x) { return x * 1/5; }
unsigned int f_0x66666667_s2(unsigned int x) { return x * 1/10; }
unsigned int f_0x66666667_s3(unsigned int x) { return x * 1/20; }
unsigned int f_0x66666667_s4(unsigned int x) { return x * 1/40; }
unsigned int f_0x66666667_s5(unsigned int x) { return x * 1/80; }
unsigned int f_0x66666667_s6(unsigned int x) { return x * 1/160; }
unsigned int f_0x66666667_s7(unsigned int x) { return x * 1/320; }
unsigned int f_0x66666667_s8(unsigned int x) { return x * 1/640; }
unsigned int f_0x6BCA1AF3_s5(unsigned int x) { return x * 1/76; }
unsigned int f_0x88888889_s8(unsigned int x) { return x * 1/480; }
unsigned int f_0x92492493_s3(unsigned int x) { return x * 1/14; }
unsigned int f_0xA0A0A0A1_s7(unsigned int x) { return x * 1/204; }
unsigned int f_0xAAAAAAAB_s1(unsigned int x) { return x * 1/3; }
unsigned int f_0xAAAAAAAB_s2(unsigned int x) { return x * 1/6; }
unsigned int f_0xAAAAAAAB_s3(unsigned int x) { return x * 1/12; }
unsigned int f_0xAAAAAAAB_s4(unsigned int x) { return x * 1/24; }
unsigned int f_0xAE147AE1_s5(unsigned int x) { return x * 17/800; }
unsigned int f_0xB21642C9_s5(unsigned int x) { return x * 1/46; }
unsigned int f_0xB60B60B7_s5(unsigned int x) { return x * 1/45; }
unsigned int f_0xBA2E8BA3_s3(unsigned int x) { return x * 1/11; }
unsigned int f_0xEA0EA0EB_s0(unsigned int x) { return x * 32/35; }

With a high optimization level, GCC will generate code making use of constants (in most cases): gcc -O3 -c mult.c -o mult.o

In ghidra, this will result in functions like:

ulong f_0x51EB851F_s5(uint uParm1)
{
  return (ulong)uParm1 * 0x51eb851f >> 0x25;
}

This is one I actually came across in the wild (this is the division by 100).

Ideally, these pattern should be recognized and replaced in the decompiler view.

Env: Ghidra 9.0.4, Linux x86_64, GCC 8.3.0

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:3
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
clienthaxcommented, Apr 4, 2020

@caheckman @ryanmkurtz Any reason this was closed, still seems to be not implemented?

image

1reaction
paulsappscommented, Jun 11, 2019

A related feature would be to have an option to convert shifts to multiply/divides too

Read more comments on GitHub >

github_iconTop Results From Across the Web

How can I reverse optimized integer division/modulo by ...
The Reko decompiler recovers the integer divisors by performing a divide and conquer search using mediants. Reko starts by recognizing the ...
Read more >
Fast integer division and modulo with a const runtime divisor
This is a perfect use-case for libdivide. This library has been designed to speed up division by constant at run-time by using the...
Read more >
How do compilers optimize divisions? - Hacker News
For divisions by a constant value that don't easily decompose into shifts you can fall back to multiplication by a magic constant which...
Read more >
Divide two integers without using multiplication, division and ...
Given two integers say a and b. Find the quotient after dividing a by b without using multiplication, division, and mod operator. Example:...
Read more >
Optimizations in C++ Compilers | February 2020
The compiler recognizes that some expressions within a loop are constant for the duration of that loop ... Integer division by a constant....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found