diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc
index bbf60de3b1b..845dd4c1e50 100644
--- a/gcc/config/rs6000/rs6000-builtin.cc
+++ b/gcc/config/rs6000/rs6000-builtin.cc
@@ -3288,7 +3288,8 @@ rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */,
       || fcode == RS6000_BIF_PPC_ATOMIC_CAS_HI
       || fcode == RS6000_BIF_PPC_ATOMIC_CAS_SI
       || fcode == RS6000_BIF_PPC_ATOMIC_CAS_DI
-      || fcode == RS6000_BIF_PPC_ATOMIC_CAS_TI)
+      || fcode == RS6000_BIF_PPC_ATOMIC_CAS_TI
+      || fcode == RS6000_BIF_PPC_ATOMIC_CAS_DI_LL)
     {
       machine_mode mode; // Get mode based on BIF ID (QImode, SImode, etc.)
 
@@ -3307,13 +3308,21 @@ rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */,
 	  icode = CODE_FOR_atomic_compare_and_swap_localsi;
 	  break;
 	case RS6000_BIF_PPC_ATOMIC_CAS_DI:
-	  mode = DImode;
-	  icode = CODE_FOR_atomic_compare_and_swap_localdi;
+	  mode = TARGET_32BIT ? SImode : DImode;
+	  icode = TARGET_32BIT ? CODE_FOR_atomic_compare_and_swap_localsi
+			       : CODE_FOR_atomic_compare_and_swap_localdi;
 	  break;
 	case RS6000_BIF_PPC_ATOMIC_CAS_TI:
 	  mode = TImode;
 	  icode = CODE_FOR_atomic_compare_and_swap_localti;
 	  break;
+	case RS6000_BIF_PPC_ATOMIC_CAS_DI_LL:
+	  if (TARGET_32BIT)
+	    error ("Invalid arguments to %qs",
+		   "__builtin_ppc_atomic_cas_local");
+	  mode = DImode;
+	  icode = CODE_FOR_atomic_compare_and_swap_localdi;
+	  break;
 	default:
 	  gcc_unreachable ();
 	}
diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def
index 577c9d6c8f0..a7918b4184d 100644
--- a/gcc/config/rs6000/rs6000-builtins.def
+++ b/gcc/config/rs6000/rs6000-builtins.def
@@ -255,6 +255,8 @@
     PPC_ATOMIC_CAS_SI nothing {}
   bool __builtin_ppc_atomic_cas_local_di (long *, long *, long *, const int, const int, const int);
     PPC_ATOMIC_CAS_DI nothing {}
+  bool __builtin_ppc_atomic_cas_local_di_ll (long long *, long long *, long long *, const int, const int, const int);
+    PPC_ATOMIC_CAS_DI_LL nothing {}
   bool __builtin_ppc_atomic_cas_local_ti (vsq *, vsq *, vsq *, const int, const int, const int);
     PPC_ATOMIC_CAS_TI nothing {}
 
diff --git a/gcc/config/rs6000/rs6000-overload.def b/gcc/config/rs6000/rs6000-overload.def
index 8f2fa978475..6ee90c0f8c7 100644
--- a/gcc/config/rs6000/rs6000-overload.def
+++ b/gcc/config/rs6000/rs6000-overload.def
@@ -96,6 +96,10 @@
     PPC_ATOMIC_CAS_DI PPC_ATOMIC_CAS_SDI
   bool __builtin_ppc_atomic_cas_local (unsigned long *, unsigned long *, unsigned long *, const int, const int, const int);
     PPC_ATOMIC_CAS_DI PPC_ATOMIC_CAS_UDI
+  bool __builtin_ppc_atomic_cas_local (signed long long *, signed long long *, signed long long *, const int, const int, const int);
+    PPC_ATOMIC_CAS_DI_LL PPC_ATOMIC_CAS_SDI_LL
+  bool __builtin_ppc_atomic_cas_local (unsigned long long *, unsigned long long *, unsigned long long *, const int, const int, const int);
+    PPC_ATOMIC_CAS_DI_LL PPC_ATOMIC_CAS_UDI_LL
   bool __builtin_ppc_atomic_cas_local (vsq *, vsq *, vsq *, const int, const int, const int);
     PPC_ATOMIC_CAS_TI PPC_ATOMIC_CAS_STI
   bool __builtin_ppc_atomic_cas_local (vuq *, vuq *, vuq *, const int, const int, const int);
diff --git a/gcc/testsuite/gcc.target/powerpc/acmp-tst-32-fail.c b/gcc/testsuite/gcc.target/powerpc/acmp-tst-32-fail.c
new file mode 100644
index 00000000000..c466d7bb18e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/acmp-tst-32-fail.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2 -m32" } */
+
+#define TESTS \
+  X(signed long long, sdi) \
+  X(unsigned long long, udi)
+
+#define X(T, name) \
+bool word_exchange_##name (T *ptr, T *expected, T * desired) \
+{ \
+  return __builtin_ppc_atomic_cas_local (ptr, expected, desired, 0, \
+					 __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE); \
+}
+
+TESTS
+
+/* { dg-excess-errors "This test is expected to fail on 32-bit" { target ilp32 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/acmp-tst-32.c b/gcc/testsuite/gcc.target/powerpc/acmp-tst-32.c
new file mode 100644
index 00000000000..6763cee5ff8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/acmp-tst-32.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2 -m32" } */
+
+#define TESTS \
+  X(signed char, qi) \
+  X(unsigned char, uqi) \
+  X(short, hi) \
+  X(signed short, shi) \
+  X(unsigned short, uhi) \
+  X(int, si) \
+  X(signed int, ssi) \
+  X(unsigned int, usi) \
+  X(long, di) \
+  X(signed long, sdi) \
+  X(unsigned long, udi)
+
+#define X(T, name) \
+bool word_exchange_##name (T *ptr, T *expected, T * desired) \
+{ \
+  return __builtin_ppc_atomic_cas_local (ptr, expected, desired, 0, \
+					 __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE); \
+}
+
+TESTS
+
+/* { dg-final { scan-assembler-times {\mlbarx +[0-9]+,[0-9]+,[0-9]+,1} 2 } } */
+/* { dg-final { scan-assembler-times {\mlharx +[0-9]+,[0-9]+,[0-9]+,1} 3 } } */
+/* { dg-final { scan-assembler-times {\mlwarx +[0-9]+,[0-9]+,[0-9]+,1} 6 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/acmp-tst.c b/gcc/testsuite/gcc.target/powerpc/acmp-tst.c
index 6ebd2ebbc28..27c98c37acf 100644
--- a/gcc/testsuite/gcc.target/powerpc/acmp-tst.c
+++ b/gcc/testsuite/gcc.target/powerpc/acmp-tst.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-require-effective-target int128 } */
 /* { dg-options "-O2" } */
 
 #define TESTS \
@@ -13,6 +14,8 @@
   X(long, di) \
   X(signed long, sdi) \
   X(unsigned long, udi) \
+  X(signed long long, sdi2) \
+  X(unsigned long long, udi2) \
   X(vector signed __int128, sti) \
   X(vector unsigned __int128, uti)
 
@@ -28,5 +31,5 @@ TESTS
 /* { dg-final { scan-assembler-times {\mlbarx +[0-9]+,[0-9]+,[0-9]+,1} 2 } } */
 /* { dg-final { scan-assembler-times {\mlharx +[0-9]+,[0-9]+,[0-9]+,1} 3 } } */
 /* { dg-final { scan-assembler-times {\mlwarx +[0-9]+,[0-9]+,[0-9]+,1} 3 } } */
-/* { dg-final { scan-assembler-times {\mldarx +[0-9]+,[0-9]+,[0-9]+,1} 3 } } */
+/* { dg-final { scan-assembler-times {\mldarx +[0-9]+,[0-9]+,[0-9]+,1} 5 } } */
 /* { dg-final { scan-assembler-times {\mlqarx +[0-9]+,[0-9]+,[0-9]+,1} 2 } } */
