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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions