diff --git a/gcc/builtins.c b/gcc/builtins.c
index 6b25253..79616df 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -2819,8 +2819,7 @@ expand_builtin_strlen (tree exp, rtx target,
 {
   if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
     return NULL_RTX;
-  else
-    {
+
   struct expand_operand ops[4];
   rtx pat;
   tree len;
@@ -2883,7 +2882,7 @@ expand_builtin_strlen (tree exp, rtx target,
   /* Check to see if the argument was declared attribute nonstring
      and if so, issue a warning since at this point it's not known
      to be nul-terminated.  */
-      maybe_warn_nonstring_arg (TREE_OPERAND (CALL_EXPR_FN (exp), 0), exp);
+  maybe_warn_nonstring_arg (get_callee_fndecl (exp), exp);
 
   /* Now that we are assured of success, expand the source.  */
   start_sequence ();
@@ -2915,7 +2914,6 @@ expand_builtin_strlen (tree exp, rtx target,
 
   return target;
 }
-}
 
 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
    bytes from constant string DATA + OFFSET and return it as target
@@ -4426,13 +4424,11 @@ expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
 
   insn_code cmpstr_icode = direct_optab_handler (cmpstr_optab, SImode);
   insn_code cmpstrn_icode = direct_optab_handler (cmpstrn_optab, SImode);
-  if (cmpstr_icode != CODE_FOR_nothing || cmpstrn_icode != CODE_FOR_nothing)
-    {
-      rtx arg1_rtx, arg2_rtx;
-      tree fndecl, fn;
+  if (cmpstr_icode == CODE_FOR_nothing && cmpstrn_icode == CODE_FOR_nothing)
+    return NULL_RTX;
+
   tree arg1 = CALL_EXPR_ARG (exp, 0);
   tree arg2 = CALL_EXPR_ARG (exp, 1);
-      rtx result = NULL_RTX;
 
   unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
   unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
@@ -4445,9 +4441,10 @@ expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
   arg1 = builtin_save_expr (arg1);
   arg2 = builtin_save_expr (arg2);
 
-      arg1_rtx = get_memory_rtx (arg1, NULL);
-      arg2_rtx = get_memory_rtx (arg2, NULL);
+  rtx arg1_rtx = get_memory_rtx (arg1, NULL);
+  rtx arg2_rtx = get_memory_rtx (arg2, NULL);
 
+  rtx result = NULL_RTX;
   /* Try to call cmpstrsi.  */
   if (cmpstr_icode != CODE_FOR_nothing)
     result = expand_cmpstr (cmpstr_icode, target, arg1_rtx, arg2_rtx,
@@ -4501,6 +4498,12 @@ expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
 	}
     }
 
+  /* Check to see if the argument was declared attribute nonstring
+     and if so, issue a warning since at this point it's not known
+     to be nul-terminated.  */
+  tree fndecl = get_callee_fndecl (exp);
+  maybe_warn_nonstring_arg (fndecl, exp);
+
   if (result)
     {
       /* Return the value in the proper mode for this function.  */
@@ -4515,14 +4518,11 @@ expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
 
   /* Expand the library call ourselves using a stabilized argument
      list to avoid re-evaluating the function's arguments twice.  */
-      fndecl = get_callee_fndecl (exp);
-      fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 2, arg1, arg2);
+  tree fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 2, arg1, arg2);
   gcc_assert (TREE_CODE (fn) == CALL_EXPR);
   CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
   return expand_call (fn, target, target == const0_rtx);
 }
-  return NULL_RTX;
-}
 
 /* Expand expression EXP, which is a call to the strncmp builtin. Return
    NULL_RTX if we failed the caller should emit a normal call, otherwise try to get
@@ -4532,8 +4532,6 @@ static rtx
 expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
 			ATTRIBUTE_UNUSED machine_mode mode)
 {
-  location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp);
-
   if (!validate_arglist (exp,
  			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
     return NULL_RTX;
@@ -4542,12 +4540,11 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
      lengths, and it doesn't have side effects, then emit cmpstrnsi
      using length MIN(strlen(string)+1, arg3).  */
   insn_code cmpstrn_icode = direct_optab_handler (cmpstrn_optab, SImode);
-  if (cmpstrn_icode != CODE_FOR_nothing)
-  {
-    tree len, len1, len2, len3;
-    rtx arg1_rtx, arg2_rtx, arg3_rtx;
-    rtx result;
-    tree fndecl, fn;
+  if (cmpstrn_icode == CODE_FOR_nothing)
+    return NULL_RTX;
+
+  tree len;
+
   tree arg1 = CALL_EXPR_ARG (exp, 0);
   tree arg2 = CALL_EXPR_ARG (exp, 1);
   tree arg3 = CALL_EXPR_ARG (exp, 2);
@@ -4555,15 +4552,17 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
   unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
   unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
 
-    len1 = c_strlen (arg1, 1);
-    len2 = c_strlen (arg2, 1);
+  tree len1 = c_strlen (arg1, 1);
+  tree len2 = c_strlen (arg2, 1);
+
+  location_t loc = EXPR_LOCATION (exp);
 
   if (len1)
     len1 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len1);
   if (len2)
     len2 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len2);
 
-    len3 = fold_convert_loc (loc, sizetype, arg3);
+  tree len3 = fold_convert_loc (loc, sizetype, arg3);
 
   /* If we don't have a constant length for the first, use the length
      of the second, if we know it.  If neither string is constant length,
@@ -4596,12 +4595,19 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
      The actual new length parameter will be MIN(len,arg3) in this case.  */
   if (len != len3)
     len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len, len3);
-    arg1_rtx = get_memory_rtx (arg1, len);
-    arg2_rtx = get_memory_rtx (arg2, len);
-    arg3_rtx = expand_normal (len);
-    result = expand_cmpstrn_or_cmpmem (cmpstrn_icode, target, arg1_rtx,
+  rtx arg1_rtx = get_memory_rtx (arg1, len);
+  rtx arg2_rtx = get_memory_rtx (arg2, len);
+  rtx arg3_rtx = expand_normal (len);
+  rtx result = expand_cmpstrn_or_cmpmem (cmpstrn_icode, target, arg1_rtx,
 					 arg2_rtx, TREE_TYPE (len), arg3_rtx,
 					 MIN (arg1_align, arg2_align));
+
+  /* Check to see if the argument was declared attribute nonstring
+     and if so, issue a warning since at this point it's not known
+     to be nul-terminated.  */
+  tree fndecl = get_callee_fndecl (exp);
+  maybe_warn_nonstring_arg (fndecl, exp);
+
   if (result)
     {
       /* Return the value in the proper mode for this function.  */
@@ -4616,15 +4622,11 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
 
   /* Expand the library call ourselves using a stabilized argument
      list to avoid re-evaluating the function's arguments twice.  */
-    fndecl = get_callee_fndecl (exp);
-    fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 3,
-				arg1, arg2, len);
+  tree fn = build_call_nofold_loc (loc, fndecl, 3, arg1, arg2, len);
   gcc_assert (TREE_CODE (fn) == CALL_EXPR);
   CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
   return expand_call (fn, target, target == const0_rtx);
 }
-  return NULL_RTX;
-}
 
 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
    if that's convenient.  */
diff --git a/gcc/testsuite/c-c++-common/attr-nonstring-4.c b/gcc/testsuite/c-c++-common/attr-nonstring-4.c
new file mode 100644
index 0000000..786e647
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/attr-nonstring-4.c
@@ -0,0 +1,71 @@
+/* PR middle-end/83131 - c-c++/common/attr-nonstring-3 failure for strcmp
+   tests on PowerPC
+   { dg-do compile }
+   { dg-options "-O2 -Wstringop-overflow -ftrack-macro-expansion=0" }  */
+
+typedef __SIZE_TYPE__ size_t;
+
+extern int strcmp (const char*, const char*);
+extern int strncmp (const char*, const char*, size_t);
+
+extern char arx[] __attribute__ ((nonstring));
+extern char ar5[5] __attribute__ ((nonstring));
+extern char str[];
+
+enum { N = sizeof ar5 };
+enum { X = sizeof ar5 + 1 };
+
+
+int warn_strcmp_cst_1 (void)
+{
+  return strcmp ("bar", arx);       /* { dg-warning "argument 2 declared attribute .nonstring." } */
+}
+
+int warn_strcmp_cst_2 (void)
+{
+  return strcmp (arx, "foo");       /* { dg-warning "argument 1 declared attribute .nonstring." } */
+}
+
+
+int warn_strncmp_cst_1 (void)
+{
+  return strncmp ("bar", ar5, X);   /* { dg-warning "argument 2 declared attribute .nonstring." } */
+}
+
+int warn_strncmp_cst_2 (void)
+{
+  return strncmp (ar5, "foo", X);   /* { dg-warning "argument 1 declared attribute .nonstring." } */
+}
+
+
+int nowarn_strncmp_cst_1 (void)
+{
+  return strncmp ("bar", ar5, N);
+}
+
+int nowarn_strncmp_cst_2 (void)
+{
+  return strncmp (ar5, "foo", N);
+}
+
+
+int warn_strncmp_var_1 (void)
+{
+  return strncmp (str, ar5, X);     /* { dg-warning "argument 2 declared attribute .nonstring." } */
+}
+
+int warn_strncmp_var_2 (void)
+{
+  return strncmp (ar5, str, X);     /* { dg-warning "argument 1 declared attribute .nonstring." } */
+}
+
+
+int nowarn_strncmp_var_1 (void)
+{
+  return strncmp (str, ar5, N);
+}
+
+int nowarn_strncmp_var_2 (void)
+{
+  return strncmp (ar5, str, N);
+}
