Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -10405,6 +10405,41 @@ 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: Index: test/CodeGen/adc-builtins.c =================================================================== --- test/CodeGen/adc-builtins.c +++ 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 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 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); } Index: test/CodeGen/adx-builtins.c =================================================================== --- test/CodeGen/adx-builtins.c +++ 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 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); }