From: Craig Topper Date: Fri, 7 Sep 2018 16:58:57 +0000 (+0000) Subject: [X86] Modify addcarry/subborrow builtins to emit an 2 result and intrinsic and an... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=26a2dfb9c8caef4c438191af138f396f76c2ba46;p=clang [X86] Modify addcarry/subborrow builtins to emit an 2 result and intrinsic and an store instruction. This is the clang side of D51769. The llvm intrinsics now return two results instead of using an out parameter. Differential Revision: https://reviews.llvm.org/D51771 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@341678 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 789f01cc82..a472bf59d7 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -10405,6 +10405,41 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, Ops[0]); return Builder.CreateExtractValue(Call, 1); } + case X86::BI__builtin_ia32_addcarryx_u32: + case X86::BI__builtin_ia32_addcarryx_u64: + case X86::BI__builtin_ia32_addcarry_u32: + case X86::BI__builtin_ia32_addcarry_u64: + case X86::BI__builtin_ia32_subborrow_u32: + case X86::BI__builtin_ia32_subborrow_u64: { + Intrinsic::ID IID; + switch (BuiltinID) { + default: llvm_unreachable("Unsupported intrinsic!"); + case X86::BI__builtin_ia32_addcarryx_u32: + IID = Intrinsic::x86_addcarryx_u32; + break; + case X86::BI__builtin_ia32_addcarryx_u64: + IID = Intrinsic::x86_addcarryx_u64; + break; + case X86::BI__builtin_ia32_addcarry_u32: + IID = Intrinsic::x86_addcarry_u32; + break; + case X86::BI__builtin_ia32_addcarry_u64: + IID = Intrinsic::x86_addcarry_u64; + break; + case X86::BI__builtin_ia32_subborrow_u32: + IID = Intrinsic::x86_subborrow_u32; + break; + case X86::BI__builtin_ia32_subborrow_u64: + IID = Intrinsic::x86_subborrow_u64; + break; + } + + Value *Call = Builder.CreateCall(CGM.getIntrinsic(IID), + { Ops[0], Ops[1], Ops[2] }); + Builder.CreateDefaultAlignedStore(Builder.CreateExtractValue(Call, 1), + Ops[3]); + return Builder.CreateExtractValue(Call, 0); + } case X86::BI__builtin_ia32_fpclassps128_mask: case X86::BI__builtin_ia32_fpclassps256_mask: diff --git a/test/CodeGen/adc-builtins.c b/test/CodeGen/adc-builtins.c index d41fa8f446..feb6671742 100644 --- a/test/CodeGen/adc-builtins.c +++ b/test/CodeGen/adc-builtins.c @@ -5,7 +5,10 @@ unsigned char test_addcarry_u32(unsigned char __cf, unsigned int __x, unsigned int __y, unsigned int *__p) { // CHECK-LABEL: test_addcarry_u32 -// CHECK: call i8 @llvm.x86.addcarry.u32 +// CHECK: [[ADC:%.*]] = call { i8, i32 } @llvm.x86.addcarry.u32 +// CHECK: [[DATA:%.*]] = extractvalue { i8, i32 } [[ADC]], 1 +// CHECK: store i32 [[DATA]], i32* %{{.*}} +// CHECK: [[CF:%.*]] = extractvalue { i8, i32 } [[ADC]], 0 return _addcarry_u32(__cf, __x, __y, __p); } @@ -13,14 +16,20 @@ unsigned char test_addcarry_u64(unsigned char __cf, unsigned long long __x, unsigned long long __y, unsigned long long *__p) { // CHECK-LABEL: test_addcarry_u64 -// CHECK: call i8 @llvm.x86.addcarry.u64 +// CHECK: [[ADC:%.*]] = call { i8, i64 } @llvm.x86.addcarry.u64 +// CHECK: [[DATA:%.*]] = extractvalue { i8, i64 } [[ADC]], 1 +// CHECK: store i64 [[DATA]], i64* %{{.*}} +// CHECK: [[CF:%.*]] = extractvalue { i8, i64 } [[ADC]], 0 return _addcarry_u64(__cf, __x, __y, __p); } unsigned char test_subborrow_u32(unsigned char __cf, unsigned int __x, unsigned int __y, unsigned int *__p) { // CHECK-LABEL: test_subborrow_u32 -// CHECK: call i8 @llvm.x86.subborrow.u32 +// CHECK: [[SBB:%.*]] = call { i8, i32 } @llvm.x86.subborrow.u32 +// CHECK: [[DATA:%.*]] = extractvalue { i8, i32 } [[SBB]], 1 +// CHECK: store i32 [[DATA]], i32* %{{.*}} +// CHECK: [[CF:%.*]] = extractvalue { i8, i32 } [[SBB]], 0 return _subborrow_u32(__cf, __x, __y, __p); } @@ -28,6 +37,9 @@ unsigned char test_subborrow_u64(unsigned char __cf, unsigned long long __x, unsigned long long __y, unsigned long long *__p) { // CHECK-LABEL: test_subborrow_u64 -// CHECK: call i8 @llvm.x86.subborrow.u64 +// CHECK: [[SBB:%.*]] = call { i8, i64 } @llvm.x86.subborrow.u64 +// CHECK: [[DATA:%.*]] = extractvalue { i8, i64 } [[SBB]], 1 +// CHECK: store i64 [[DATA]], i64* %{{.*}} +// CHECK: [[CF:%.*]] = extractvalue { i8, i64 } [[SBB]], 0 return _subborrow_u64(__cf, __x, __y, __p); } diff --git a/test/CodeGen/adx-builtins.c b/test/CodeGen/adx-builtins.c index ac33367d0e..8fd95c005b 100644 --- a/test/CodeGen/adx-builtins.c +++ b/test/CodeGen/adx-builtins.c @@ -5,7 +5,10 @@ unsigned char test_addcarryx_u32(unsigned char __cf, unsigned int __x, unsigned int __y, unsigned int *__p) { // CHECK-LABEL: test_addcarryx_u32 -// CHECK: call i8 @llvm.x86.addcarryx.u32 +// CHECK: [[ADC:%.*]] = call { i8, i32 } @llvm.x86.addcarryx.u32 +// CHECK: [[DATA:%.*]] = extractvalue { i8, i32 } [[ADC]], 1 +// CHECK: store i32 [[DATA]], i32* %{{.*}} +// CHECK: [[CF:%.*]] = extractvalue { i8, i32 } [[ADC]], 0 return _addcarryx_u32(__cf, __x, __y, __p); } @@ -13,6 +16,9 @@ unsigned char test_addcarryx_u64(unsigned char __cf, unsigned long long __x, unsigned long long __y, unsigned long long *__p) { // CHECK-LABEL: test_addcarryx_u64 -// CHECK: call i8 @llvm.x86.addcarryx.u64 +// CHECK: [[ADC:%.*]] = call { i8, i64 } @llvm.x86.addcarryx.u64 +// CHECK: [[DATA:%.*]] = extractvalue { i8, i64 } [[ADC]], 1 +// CHECK: store i64 [[DATA]], i64* %{{.*}} +// CHECK: [[CF:%.*]] = extractvalue { i8, i64 } [[ADC]], 0 return _addcarryx_u64(__cf, __x, __y, __p); }