diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 703541d15cc..7e94bd78b98 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -306,14 +306,15 @@ public:
 class ipcp_bits_lattice
 {
 public:
-  bool bottom_p () { return m_lattice_val == IPA_BITS_VARYING; }
-  bool top_p () { return m_lattice_val == IPA_BITS_UNDEFINED; }
-  bool constant_p () { return m_lattice_val == IPA_BITS_CONSTANT; }
+  bool bottom_p () const { return m_lattice_val == IPA_BITS_VARYING; }
+  bool top_p () const { return m_lattice_val == IPA_BITS_UNDEFINED; }
+  bool constant_p () const { return m_lattice_val == IPA_BITS_CONSTANT; }
   bool set_to_bottom ();
   bool set_to_constant (widest_int, widest_int);
+  bool known_nonzero_p () const;
 
-  widest_int get_value () { return m_value; }
-  widest_int get_mask () { return m_mask; }
+  widest_int get_value () const { return m_value; }
+  widest_int get_mask () const { return m_mask; }
 
   bool meet_with (ipcp_bits_lattice& other, unsigned, signop,
 		  enum tree_code, tree);
@@ -1081,6 +1082,15 @@ ipcp_bits_lattice::set_to_constant (widest_int value, widest_int mask)
   return true;
 }
 
+/* Return true if any of the known bits are non-zero.  */
+bool
+ipcp_bits_lattice::known_nonzero_p () const
+{
+  if (!constant_p ())
+    return false;
+  return !wi::eq_p (wi::bit_and (wi::bit_not (m_mask), m_value), 0);
+}
+
 /* Convert operand to value, mask form.  */
 
 void
@@ -2374,6 +2384,7 @@ propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
       tree operand = NULL_TREE;
       enum tree_code code;
       unsigned src_idx;
+      bool only_for_nonzero = false;
 
       if (jfunc->type == IPA_JF_PASS_THROUGH)
 	{
@@ -2386,7 +2397,9 @@ propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
 	{
 	  code = POINTER_PLUS_EXPR;
 	  src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
-	  unsigned HOST_WIDE_INT offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;
+	  unsigned HOST_WIDE_INT offset
+	    = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;
+	  only_for_nonzero = (ipa_get_jf_ancestor_keep_null (jfunc) || !offset);
 	  operand = build_int_cstu (size_type_node, offset);
 	}
 
@@ -2404,16 +2417,18 @@ propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
 	 and we store it in jump function during analysis stage.  */
 
       if (src_lats->bits_lattice.bottom_p ()
-	  && jfunc->bits)
-	return dest_lattice->meet_with (jfunc->bits->value, jfunc->bits->mask,
-					precision);
+	  || (only_for_nonzero && !src_lats->bits_lattice.known_nonzero_p ()))
+	{
+	  if (jfunc->bits)
+	    return dest_lattice->meet_with (jfunc->bits->value,
+					    jfunc->bits->mask, precision);
+	  else
+	    return dest_lattice->set_to_bottom ();
+	}
       else
 	return dest_lattice->meet_with (src_lats->bits_lattice, precision, sgn,
 					code, operand);
     }
-
-  else if (jfunc->type == IPA_JF_ANCESTOR)
-    return dest_lattice->set_to_bottom ();
   else if (jfunc->bits)
     return dest_lattice->meet_with (jfunc->bits->value, jfunc->bits->mask,
 				    precision);
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index e85df0971fc..7d19e30e3f5 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -357,6 +357,8 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
 		   jump_func->value.ancestor.offset);
 	  if (jump_func->value.ancestor.agg_preserved)
 	    fprintf (f, ", agg_preserved");
+	  if (jump_func->value.ancestor.keep_null)
+	    fprintf (f, ", keep_null");
 	  fprintf (f, "\n");
 	}
 
@@ -601,12 +603,13 @@ ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
 
 static void
 ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
-		     int formal_id, bool agg_preserved)
+		     int formal_id, bool agg_preserved, bool keep_null)
 {
   jfunc->type = IPA_JF_ANCESTOR;
   jfunc->value.ancestor.formal_id = formal_id;
   jfunc->value.ancestor.offset = offset;
   jfunc->value.ancestor.agg_preserved = agg_preserved;
+  jfunc->value.ancestor.keep_null = keep_null;
 }
 
 /* Get IPA BB information about the given BB.  FBI is the context of analyzis
@@ -1438,7 +1441,8 @@ compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
   index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa));
   if (index >= 0 && param_type && POINTER_TYPE_P (param_type))
     ipa_set_ancestor_jf (jfunc, offset,  index,
-			 parm_ref_data_pass_through_p (fbi, index, call, ssa));
+			 parm_ref_data_pass_through_p (fbi, index, call, ssa),
+			 false);
 }
 
 /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
@@ -1564,7 +1568,8 @@ compute_complex_ancestor_jump_func (struct ipa_func_body_info *fbi,
     }
 
   ipa_set_ancestor_jf (jfunc, offset, index,
-		       parm_ref_data_pass_through_p (fbi, index, call, parm));
+		       parm_ref_data_pass_through_p (fbi, index, call, parm),
+		       true);
 }
 
 /* Inspect the given TYPE and return true iff it has the same structure (the
@@ -3327,7 +3332,8 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 		    ipa_set_ancestor_jf (dst,
 					 ipa_get_jf_ancestor_offset (src),
 					 ipa_get_jf_ancestor_formal_id (src),
-					 agg_p);
+					 agg_p,
+					 ipa_get_jf_ancestor_keep_null (src));
 		    break;
 		  }
 		default:
@@ -4758,6 +4764,7 @@ ipa_write_jump_function (struct output_block *ob,
       streamer_write_uhwi (ob, jump_func->value.ancestor.formal_id);
       bp = bitpack_create (ob->main_stream);
       bp_pack_value (&bp, jump_func->value.ancestor.agg_preserved, 1);
+      bp_pack_value (&bp, jump_func->value.ancestor.keep_null, 1);
       streamer_write_bitpack (&bp);
       break;
     default:
@@ -4883,7 +4890,9 @@ ipa_read_jump_function (class lto_input_block *ib,
 	int formal_id = streamer_read_uhwi (ib);
 	struct bitpack_d bp = streamer_read_bitpack (ib);
 	bool agg_preserved = bp_unpack_value (&bp, 1);
-	ipa_set_ancestor_jf (jump_func, offset, formal_id, agg_preserved);
+	bool keep_null = bp_unpack_value (&bp, 1);
+	ipa_set_ancestor_jf (jump_func, offset, formal_id, agg_preserved,
+			     keep_null);
 	break;
       }
     default:
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 42842d9466a..8f0039d1ef8 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -143,6 +143,8 @@ struct GTY(()) ipa_ancestor_jf_data
   int formal_id;
   /* Flag with the same meaning like agg_preserve in ipa_pass_through_data.  */
   unsigned agg_preserved : 1;
+  /* When set, the operation should not have any effect on NULL pointers.  */
+  unsigned keep_null : 1;
 };
 
 /* A jump function for an aggregate part at a given offset, which describes how
@@ -438,6 +440,17 @@ ipa_get_jf_ancestor_type_preserved (struct ipa_jump_func *jfunc)
   return jfunc->value.ancestor.agg_preserved;
 }
 
+/* Return if jfunc represents an operation whether we first check the formal
+   parameter for non-NULLness unless it does not matter because the offset is
+   zero anyway.  */
+
+static inline bool
+ipa_get_jf_ancestor_keep_null (struct ipa_jump_func *jfunc)
+{
+  gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
+  return jfunc->value.ancestor.keep_null;
+}
+
 /* Class for allocating a bundle of various potentially known properties about
    actual arguments of a particular call on stack for the usual case and on
    heap only if there are unusually many arguments.  The data is deallocated
diff --git a/gcc/testsuite/gcc.dg/ipa/pr103083.c b/gcc/testsuite/gcc.dg/ipa/pr103083.c
new file mode 100644
index 00000000000..e2fbb45d3cc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr103083.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -Wno-pointer-to-int-cast" } */
+
+struct b {int b;};
+struct a {int a; struct b b;};
+
+long i;
+
+__attribute__ ((noinline))
+static void test2 (struct b *b)
+{
+  if (((int)b)&4)
+    __builtin_abort ();
+}
+
+__attribute__ ((noinline))
+static void
+test (struct a *a)
+{
+  test2(a? &a->b : 0);
+}
+
+int
+main()
+{
+  test(0);
+  return 0;
+}
