Index: gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-1.c
===================================================================
--- gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-1.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-1.c	(working copy)
@@ -0,0 +1,30 @@
+/* Test non-canonical BID significands: _Decimal128.  Bug 91226.  */
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && lp64 } } } */
+/* { dg-options "-std=gnu2x -O2" } */
+
+extern void abort (void);
+extern void exit (int);
+
+union u
+{
+  _Decimal128 d128;
+  unsigned __int128 u128;
+};
+
+#define U128(hi, lo) (((unsigned __int128) lo) \
+		      | (((unsigned __int128) hi) << 64))
+
+int
+main (void)
+{
+  unsigned __int128 i = U128 (0x3041ed09bead87c0ULL, 0x378d8e6400000001ULL);
+  union u x;
+  _Decimal128 d128;
+  x.u128 = i;
+  d128 = x.d128;
+  volatile double d = d128;
+  if (d == 0)
+    exit (0);
+  else
+    abort ();
+}
Index: gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-2.c
===================================================================
--- gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-2.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-2.c	(working copy)
@@ -0,0 +1,42 @@
+/* Test non-canonical BID significands: _Decimal128, case where
+   combination field starts 11.  Bug 91226.  */
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && lp64 } } } */
+/* { dg-options "-std=gnu2x -O2" } */
+
+extern void abort (void);
+extern void exit (int);
+
+union u
+{
+  _Decimal128 d128;
+  unsigned __int128 u128;
+};
+
+#define U128(hi, lo) (((unsigned __int128) lo) \
+		      | (((unsigned __int128) hi) << 64))
+
+int
+main (void)
+{
+  unsigned __int128 i = U128 (0x6e79000000000000ULL, 0x1ULL);
+  union u x;
+  _Decimal128 d128;
+  x.u128 = i;
+  d128 = x.d128;
+  volatile double d = d128;
+  if (d != 0)
+    abort ();
+  /* The above number should have quantum exponent 1234.  */
+  _Decimal128 t1233 = 0.e1233DL, t1234 = 0.e1234DL, t1235 = 0.e1235DL;
+  _Decimal128 dx;
+  dx = d128 + t1233;
+  if (__builtin_memcmp (&dx, &t1233, 16) != 0)
+    abort ();
+  dx = d128 + t1234;
+  if (__builtin_memcmp (&dx, &t1234, 16) != 0)
+    abort ();
+  dx = d128 + t1235;
+  if (__builtin_memcmp (&dx, &t1234, 16) != 0)
+    abort ();
+  exit (0);
+}
Index: gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-3.c
===================================================================
--- gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-3.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-3.c	(working copy)
@@ -0,0 +1,5 @@
+/* Test non-canonical BID significands: _Decimal128.  Bug 91226.  */
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && lp64 } } } */
+/* { dg-options "-std=gnu2x -O0" } */
+
+#include "bid-non-canonical-d128-1.c"
Index: gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-4.c
===================================================================
--- gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-4.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-4.c	(working copy)
@@ -0,0 +1,6 @@
+/* Test non-canonical BID significands: _Decimal128, case where
+   combination field starts 11.  Bug 91226.  */
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && lp64 } } } */
+/* { dg-options "-std=gnu2x -O0" } */
+
+#include "bid-non-canonical-d128-2.c"
Index: gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d32-1.c
===================================================================
--- gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d32-1.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d32-1.c	(working copy)
@@ -0,0 +1,26 @@
+/* Test non-canonical BID significands: _Decimal32.  Bug 91226.  */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-std=gnu2x -O2" } */
+
+extern void abort (void);
+extern void exit (int);
+
+union u
+{
+  _Decimal32 d32;
+  unsigned int u32;
+};
+
+int
+main (void)
+{
+  union u x;
+  _Decimal32 d32;
+  x.u32 = 0x6cb89681U;
+  d32 = x.d32;
+  volatile double d = d32;
+  if (d == 0)
+    exit (0);
+  else
+    abort ();
+}
Index: gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d32-2.c
===================================================================
--- gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d32-2.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d32-2.c	(working copy)
@@ -0,0 +1,5 @@
+/* Test non-canonical BID significands: _Decimal32.  Bug 91226.  */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-std=gnu2x -O0" } */
+
+#include "bid-non-canonical-d32-1.c"
Index: gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d64-1.c
===================================================================
--- gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d64-1.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d64-1.c	(working copy)
@@ -0,0 +1,26 @@
+/* Test non-canonical BID significands: _Decimal64.  Bug 91226.  */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-std=gnu2x -O2" } */
+
+extern void abort (void);
+extern void exit (int);
+
+union u
+{
+  _Decimal64 d64;
+  unsigned long long int u64;
+};
+
+int
+main (void)
+{
+  union u x;
+  _Decimal64 d64;
+  x.u64 = 0x6c7386f26fc10001ULL;
+  d64 = x.d64;
+  volatile double d = d64;
+  if (d == 0)
+    exit (0);
+  else
+    abort ();
+}
Index: gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d64-2.c
===================================================================
--- gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d64-2.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d64-2.c	(working copy)
@@ -0,0 +1,5 @@
+/* Test non-canonical BID significands: _Decimal64.  Bug 91226.  */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-std=gnu2x -O0" } */
+
+#include "bid-non-canonical-d64-1.c"
Index: libdecnumber/bid/bid2dpd_dpd2bid.c
===================================================================
--- libdecnumber/bid/bid2dpd_dpd2bid.c	(revision 278845)
+++ libdecnumber/bid/bid2dpd_dpd2bid.c	(working copy)
@@ -189,6 +189,8 @@ _bid_to_dpd64 (_Decimal64 *pres, _Decimal64 *px) {
   if ((comb & 0xc00) == 0xc00) { /* G0..G1 = 11 -> exp is G2..G11 */
     exp = (comb) & 0x3ff;
     bcoeff = (x & 0x0007ffffffffffffull) | 0x0020000000000000ull;
+    if (bcoeff >= 10000000000000000ull)
+      bcoeff = 0;
   } else {
     exp = (comb >> 2) & 0x3ff;
     bcoeff = (x & 0x001fffffffffffffull);
@@ -298,9 +300,23 @@ _bid_to_dpd128 (_Decimal128 *pres, _Decimal128 *px
   if ((comb & 0x1e000) == 0x1e000) {
     res = x;
   } else { /* normal number */
-    exp = ((x.w[1] & 0x7fff000000000000ull) >> 49) & 0x3fff;
-    bcoeff.w[1] = (x.w[1] & 0x0001ffffffffffffull);
-    bcoeff.w[0] = x.w[0];
+    if ((comb & 0x18000) == 0x18000) {
+      /* Noncanonical significand (prepending 8 or 9 to any 110-bit
+	 trailing significand field produces a value above 10^34).  */
+      exp = (comb & 0x7fff) >> 1;
+      bcoeff.w[1] = 0;
+      bcoeff.w[0] = 0;
+    } else {
+      exp = ((x.w[1] & 0x7fff000000000000ull) >> 49) & 0x3fff;
+      bcoeff.w[1] = (x.w[1] & 0x0001ffffffffffffull);
+      bcoeff.w[0] = x.w[0];
+      if (bcoeff.w[1] > 0x1ed09bead87c0ull
+	  || (bcoeff.w[1] == 0x1ed09bead87c0ull
+	      && bcoeff.w[0] >= 0x378d8e6400000000ull)) {
+	bcoeff.w[1] = 0;
+	bcoeff.w[0] = 0;
+      }
+    }
     d1018 = reciprocals10_128[18];
     __mul_128x128_high (BH, bcoeff, d1018);
     amount = recip_scale[18];
