diff --git a/flow.c b/flow.c
index 6b2c879a..fa5d31c8 100644
--- a/flow.c
+++ b/flow.c
@@ -517,7 +517,7 @@ found:
  if (!local)
  return 0;
  check_access(insn);
- convert_load_instruction(insn, value_pseudo(0));
+ convert_load_instruction(insn, value_pseudo(insn->type, 0));
  return 1;
  }

diff --git a/linearize.c b/linearize.c
index ba76397e..2aa3acb2 100644
--- a/linearize.c
+++ b/linearize.c
@@ -785,22 +785,25 @@ static pseudo_t symbol_pseudo(struct entrypoint
*ep, struct symbol *sym)
  return pseudo;
 }

-pseudo_t value_pseudo(long long val)
+pseudo_t value_pseudo(struct symbol *type, long long val)
 {
 #define MAX_VAL_HASH 64
  static struct pseudo_list *prev[MAX_VAL_HASH];
  int hash = val & (MAX_VAL_HASH-1);
  struct pseudo_list **list = prev + hash;
+ int size = type ? type->bit_size : value_size(val);
  pseudo_t pseudo;

+
  FOR_EACH_PTR(*list, pseudo) {
- if (pseudo->value == val)
+ if (pseudo->value == val && pseudo->size == size)
  return pseudo;
  } END_FOR_EACH_PTR(pseudo);

  pseudo = __alloc_pseudo(0);
  pseudo->type = PSEUDO_VAL;
  pseudo->value = val;
+ pseudo->size = size;
  add_pseudo(list, pseudo);

  /* Value pseudos have neither nr, usage nor def */
@@ -954,10 +957,10 @@ static pseudo_t linearize_store_gen(struct entrypoint *ep,
  unsigned long long mask = (1ULL << size) - 1;

  if (shift) {
- store = add_binary_op(ep, ad->source_type, OP_SHL, value,
value_pseudo(shift));
+ store = add_binary_op(ep, ad->source_type, OP_SHL, value,
value_pseudo(ctype, shift));
  mask <<= shift;
  }
- orig = add_binary_op(ep, ad->source_type, OP_AND, orig, value_pseudo(~mask));
+ orig = add_binary_op(ep, ad->source_type, OP_AND, orig,
value_pseudo(ctype, ~mask));
  store = add_binary_op(ep, ad->source_type, OP_OR, orig, store);
  }
  add_store(ep, ad, store);
@@ -1002,7 +1005,7 @@ static pseudo_t linearize_load_gen(struct
entrypoint *ep, struct access_data *ad
  pseudo_t new = add_load(ep, ad);

  if (ctype->bit_offset) {
- pseudo_t shift = value_pseudo(ctype->bit_offset);
+ pseudo_t shift = value_pseudo(ctype, ctype->bit_offset);
  pseudo_t newval = add_binary_op(ep, ad->source_type, OP_LSR, new, shift);
  new = newval;
  }
@@ -1034,7 +1037,7 @@ static pseudo_t linearize_inc_dec(struct
entrypoint *ep, struct expression *expr
  return VOID;

  old = linearize_load_gen(ep, &ad);
- one = value_pseudo(expr->op_value);
+ one = value_pseudo(expr->ctype, expr->op_value);
  new = add_binary_op(ep, expr->ctype, op, old, one);
  linearize_store_gen(ep, new, &ad);
  finish_address_gen(ep, &ad);
@@ -1073,7 +1076,7 @@ static pseudo_t linearize_regular_preop(struct
entrypoint *ep, struct expression
  case '+':
  return pre;
  case '!': {
- pseudo_t zero = value_pseudo(0);
+ pseudo_t zero = value_pseudo(expr->ctype, 0);
  return add_binary_op(ep, expr->ctype, OP_SET_EQ, pre, zero);
  }
  case '~':
@@ -1165,7 +1168,7 @@ static inline pseudo_t
add_convert_to_bool(struct entrypoint *ep, pseudo_t src,

  if (is_bool_type(type))
  return src;
- zero = value_pseudo(0);
+ zero = value_pseudo(type, 0);
  op = OP_SET_NE;
  return add_binary_op(ep, &bool_ctype, op, src, zero);
 }
@@ -1591,7 +1594,7 @@ pseudo_t linearize_expression(struct entrypoint
*ep, struct expression *expr)
  return add_symbol_address(ep, expr->symbol);

  case EXPR_VALUE:
- return value_pseudo(expr->value);
+ return value_pseudo(expr->ctype, expr->value);

  case EXPR_STRING: case EXPR_FVALUE: case EXPR_LABEL:
  return add_setval(ep, expr->ctype, expr);
@@ -1681,7 +1684,7 @@ static pseudo_t linearize_one_symbol(struct
entrypoint *ep, struct symbol *sym)
  ad.result_type = sym;
  ad.source_type = base_type(sym);
  ad.address = symbol_pseudo(ep, sym);
- linearize_store_gen(ep, value_pseudo(0), &ad);
+ linearize_store_gen(ep, value_pseudo(sym, 0), &ad);
  }

  value = linearize_initializer(ep, sym->initializer, &ad);
diff --git a/linearize.h b/linearize.h
index bac82d7f..fd8e00d3 100644
--- a/linearize.h
+++ b/linearize.h
@@ -32,7 +32,10 @@ struct pseudo {
  int nr;
  enum pseudo_type type;
  struct pseudo_user_list *users;
- struct ident *ident;
+ union {
+ struct ident *ident;
+ int size; /* OP_SETVAL only */
+ };
  union {
  struct symbol *sym;
  struct instruction *def;
@@ -333,7 +336,8 @@ extern void insert_branch(struct basic_block *bb,
struct instruction *br, struct

 pseudo_t alloc_phi(struct basic_block *source, pseudo_t pseudo, int size);
 pseudo_t alloc_pseudo(struct instruction *def);
-pseudo_t value_pseudo(long long val);
+pseudo_t value_pseudo(struct symbol *type, long long val);
+unsigned int value_size(long long value);

 struct entrypoint *linearize_symbol(struct symbol *sym);
 int unssa(struct entrypoint *ep);
diff --git a/memops.c b/memops.c
index aeacdf56..6a795c19 100644
--- a/memops.c
+++ b/memops.c
@@ -127,7 +127,7 @@ static void simplify_loads(struct basic_block *bb)
  if (!dominators) {
  if (local) {
  assert(pseudo->type != PSEUDO_ARG);
- convert_load_instruction(insn, value_pseudo(0));
+ convert_load_instruction(insn, value_pseudo(insn->type, 0));
  }
  goto next_load;
  }
diff --git a/simplify.c b/simplify.c
index 2bc86f53..1e926e7d 100644
--- a/simplify.c
+++ b/simplify.c
@@ -352,7 +352,7 @@ static int replace_with_pseudo(struct instruction
*insn, pseudo_t pseudo)
  return REPEAT_CSE;
 }

-static unsigned int value_size(long long value)
+unsigned int value_size(long long value)
 {
  value >>= 8;
