Skip to content

Decompiler: Ghidra sometimes incorrectly optimizes bit extractions that use AND and RSHIFT #8717

@fkil

Description

@fkil

Describe the bug

I've observed several cases where Ghidra wrongfully optimizes bit extractions in such way, that the resulting condition checks for all bits in a bitmask. In all observed cases, the expression had the form (v & bitmask) >> const.

To Reproduce
Compile the following program (x64/linux) with clang -O0 -fno-stack-protector test.c -o test

#include <stdio.h>
#include <stdlib.h>


int main(int argc, char** argv) {
	if(argc <= 1) return 1;

	int v = atoi(argv[1]);
	unsigned char flags = (((v < 0) << 7) | ((v == 0x1337) << 2));

	if(((flags & 0x80u) >> 7u) != 0) {
		printf("negative!\n");
	} else {
		printf("positive!\n");
	}
}

Decompile the program in Ghidra, the output is the following:

undefined4 main(int param_1,long param_2)
{
  int iVar1;
  undefined4 local_c;
  
  local_c = 0;
  if (param_1 < 2) {
    local_c = 1;
  }
  else {
    iVar1 = atoi(*(char **)(param_2 + 8));
    if (iVar1 < 0 || iVar1 == 0x1337) {
      printf("negative!\n");
    }
    else {
      printf("positive!\n");
    }
  }
  return local_c;
}

Expected behavior

I would expect the condition to only be iVar1 < 0 and not include iVar1 == 0x1337

Environment (please complete the following information):

  • OS: Arch Linux
  • Java Version: openjdk 21.0.9 2025-10-21
  • Ghidra Version: 11.4.2
  • Ghidra Origin: official GitHub distro

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions