r184227 - [multiprecision-builtins] Added missing builtin __builtin_{add, sub}cb for {add, sub} with carry for bytes.

Michael Gottesman mgottesman at apple.com
Tue Jun 18 13:40:40 PDT 2013


Author: mgottesman
Date: Tue Jun 18 15:40:40 2013
New Revision: 184227

URL: http://llvm.org/viewvc/llvm-project?rev=184227&view=rev
Log:
[multiprecision-builtins] Added missing builtin __builtin_{add,sub}cb for {add,sub} with carry for bytes.

I have had several people ask me about why this builtin was not available in
clang (since it seems like a logical conclusion). This patch implements said
builtins.

Relevant tests are included as well. I also updated the Clang language extension reference.

rdar://14192664.

Modified:
    cfe/trunk/docs/LanguageExtensions.rst
    cfe/trunk/include/clang/Basic/Builtins.def
    cfe/trunk/lib/CodeGen/CGBuiltin.cpp
    cfe/trunk/test/CodeGen/builtins-multiprecision.c

Modified: cfe/trunk/docs/LanguageExtensions.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=184227&r1=184226&r2=184227&view=diff
==============================================================================
--- cfe/trunk/docs/LanguageExtensions.rst (original)
+++ cfe/trunk/docs/LanguageExtensions.rst Tue Jun 18 15:40:40 2013
@@ -1555,10 +1555,12 @@ The complete list of builtins are:
 
 .. code-block:: c
 
+  unsigned char      __builtin_addcb (unsigned char x, unsigned char y, unsigned char carryin, unsigned char *carryout);
   unsigned short     __builtin_addcs (unsigned short x, unsigned short y, unsigned short carryin, unsigned short *carryout);
   unsigned           __builtin_addc  (unsigned x, unsigned y, unsigned carryin, unsigned *carryout);
   unsigned long      __builtin_addcl (unsigned long x, unsigned long y, unsigned long carryin, unsigned long *carryout);
   unsigned long long __builtin_addcll(unsigned long long x, unsigned long long y, unsigned long long carryin, unsigned long long *carryout);
+  unsigned char      __builtin_subcb (unsigned char x, unsigned char y, unsigned char carryin, unsigned char *carryout);
   unsigned short     __builtin_subcs (unsigned short x, unsigned short y, unsigned short carryin, unsigned short *carryout);
   unsigned           __builtin_subc  (unsigned x, unsigned y, unsigned carryin, unsigned *carryout);
   unsigned long      __builtin_subcl (unsigned long x, unsigned long y, unsigned long carryin, unsigned long *carryout);

Modified: cfe/trunk/include/clang/Basic/Builtins.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=184227&r1=184226&r2=184227&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Builtins.def (original)
+++ cfe/trunk/include/clang/Basic/Builtins.def Tue Jun 18 15:40:40 2013
@@ -928,10 +928,12 @@ LIBBUILTIN(_Block_object_dispose, "vvC*i
 BUILTIN(__builtin_annotation, "v.", "tn")
 
 // Multiprecision Arithmetic Builtins.
+BUILTIN(__builtin_addcb, "UcUcCUcCUcCUc*", "n")
 BUILTIN(__builtin_addcs, "UsUsCUsCUsCUs*", "n")
 BUILTIN(__builtin_addc, "UiUiCUiCUiCUi*", "n")
 BUILTIN(__builtin_addcl, "ULiULiCULiCULiCULi*", "n")
 BUILTIN(__builtin_addcll, "ULLiULLiCULLiCULLiCULLi*", "n")
+BUILTIN(__builtin_subcb, "UcUcCUcCUcCUc*", "n")
 BUILTIN(__builtin_subcs, "UsUsCUsCUsCUs*", "n")
 BUILTIN(__builtin_subc, "UiUiCUiCUiCUi*", "n")
 BUILTIN(__builtin_subcl, "ULiULiCULiCULiCULi*", "n")

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=184227&r1=184226&r2=184227&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Tue Jun 18 15:40:40 2013
@@ -1345,10 +1345,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(
     StringRef Str = cast<StringLiteral>(AnnotationStrExpr)->getString();
     return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc()));
   }
+  case Builtin::BI__builtin_addcb:
   case Builtin::BI__builtin_addcs:
   case Builtin::BI__builtin_addc:
   case Builtin::BI__builtin_addcl:
   case Builtin::BI__builtin_addcll:
+  case Builtin::BI__builtin_subcb:
   case Builtin::BI__builtin_subcs:
   case Builtin::BI__builtin_subc:
   case Builtin::BI__builtin_subcl:
@@ -1382,12 +1384,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(
     llvm::Intrinsic::ID IntrinsicId;
     switch (BuiltinID) {
     default: llvm_unreachable("Unknown multiprecision builtin id.");
+    case Builtin::BI__builtin_addcb:
     case Builtin::BI__builtin_addcs:
     case Builtin::BI__builtin_addc:
     case Builtin::BI__builtin_addcl:
     case Builtin::BI__builtin_addcll:
       IntrinsicId = llvm::Intrinsic::uadd_with_overflow;
       break;
+    case Builtin::BI__builtin_subcb:
     case Builtin::BI__builtin_subcs:
     case Builtin::BI__builtin_subc:
     case Builtin::BI__builtin_subcl:

Modified: cfe/trunk/test/CodeGen/builtins-multiprecision.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtins-multiprecision.c?rev=184227&r1=184226&r2=184227&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/builtins-multiprecision.c (original)
+++ cfe/trunk/test/CodeGen/builtins-multiprecision.c Tue Jun 18 15:40:40 2013
@@ -2,6 +2,25 @@
 // RUN: %clang_cc1 -triple "x86_64-unknown-unknown" -emit-llvm -x c %s -o - -O3 | FileCheck %s
 // RUN: %clang_cc1 -triple "x86_64-mingw32"         -emit-llvm -x c %s -o - -O3 | FileCheck %s
 
+unsigned char test_addcb(unsigned char x, unsigned char y,
+                         unsigned char carryin, unsigned char *z) {
+  // CHECK: @test_addcb
+  // CHECK: %{{.+}} = {{.*}} call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %x, i8 %y)
+  // CHECK: %{{.+}} = extractvalue { i8, i1 } %{{.+}}, 1
+  // CHECK: %{{.+}} = extractvalue { i8, i1 } %{{.+}}, 0
+  // CHECK: %{{.+}} = {{.*}} call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %{{.+}}, i8 %carryin)
+  // CHECK: %{{.+}} = extractvalue { i8, i1 } %{{.+}}, 1
+  // CHECK: %{{.+}} = extractvalue { i8, i1 } %{{.+}}, 0
+  // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
+  // CHECK: %{{.+}} = zext i1 %{{.+}} to i8
+  // CHECK: store i8 %{{.+}}, i8* %z, align 1
+
+  unsigned char carryout;
+  *z = __builtin_addcb(x, y, carryin, &carryout);
+
+  return carryout;
+}
+
 unsigned short test_addcs(unsigned short x, unsigned short y,
                           unsigned short carryin, unsigned short *z) {
   // CHECK: @test_addcs
@@ -75,6 +94,25 @@ unsigned long long test_addcll(unsigned
 
   return carryout;
 }
+
+unsigned char test_subcb(unsigned char x, unsigned char y,
+                         unsigned char carryin, unsigned char *z) {
+  // CHECK: @test_subcb
+  // CHECK: %{{.+}} = {{.*}} call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %x, i8 %y)
+  // CHECK: %{{.+}} = extractvalue { i8, i1 } %{{.+}}, 1
+  // CHECK: %{{.+}} = extractvalue { i8, i1 } %{{.+}}, 0
+  // CHECK: %{{.+}} = {{.*}} call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %{{.+}}, i8 %carryin)
+  // CHECK: %{{.+}} = extractvalue { i8, i1 } %{{.+}}, 1
+  // CHECK: %{{.+}} = extractvalue { i8, i1 } %{{.+}}, 0
+  // CHECK: %{{.+}} = or i1 %{{.+}}, %{{.+}}
+  // CHECK: %{{.+}} = zext i1 %{{.+}} to i8
+  // CHECK: store i8 %{{.+}}, i8* %z, align 1
+
+  unsigned char carryout;
+  *z = __builtin_subcb(x, y, carryin, &carryout);
+
+  return carryout;
+}
 
 unsigned short test_subcs(unsigned short x, unsigned short y,
                           unsigned short carryin, unsigned short *z) {





More information about the cfe-commits mailing list