forked from OSchip/llvm-project
[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. llvm-svn: 184227
This commit is contained in:
parent
cc0273d784
commit
1534399059
|
@ -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);
|
||||
|
|
|
@ -928,10 +928,12 @@ LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES)
|
|||
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")
|
||||
|
|
|
@ -1345,10 +1345,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
|
|||
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(const FunctionDecl *FD,
|
|||
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:
|
||||
|
|
|
@ -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
|
||||
|
@ -76,6 +95,25 @@ unsigned long long test_addcll(unsigned long long x, unsigned long long y,
|
|||
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) {
|
||||
// CHECK: @test_subcs
|
||||
|
|
Loading…
Reference in New Issue