From: Tim Northover Date: Fri, 13 Jun 2014 14:24:59 +0000 (+0000) Subject: IR-change: cmpxchg operations now return { iN, i1 }. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5b50a4b409404dab20109a2d6489e87e37a49b38;p=clang IR-change: cmpxchg operations now return { iN, i1 }. This is a minimal fix for clang. I'll soon add support for generating weak variants when requested, but that's not really necessary for the LLVM change in isolation. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@210907 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGAtomic.cpp b/lib/CodeGen/CGAtomic.cpp index 18eb065226..ad4ba88dc1 100644 --- a/lib/CodeGen/CGAtomic.cpp +++ b/lib/CodeGen/CGAtomic.cpp @@ -186,13 +186,14 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, llvm::LoadInst *Desired = CGF.Builder.CreateLoad(Val2); Desired->setAlignment(Align); - llvm::AtomicCmpXchgInst *Old = CGF.Builder.CreateAtomicCmpXchg( + llvm::AtomicCmpXchgInst *Pair = CGF.Builder.CreateAtomicCmpXchg( Ptr, Expected, Desired, SuccessOrder, FailureOrder); - Old->setVolatile(E->isVolatile()); + Pair->setVolatile(E->isVolatile()); // Cmp holds the result of the compare-exchange operation: true on success, // false on failure. - llvm::Value *Cmp = CGF.Builder.CreateICmpEQ(Old, Expected); + llvm::Value *Old = CGF.Builder.CreateExtractValue(Pair, 0); + llvm::Value *Cmp = CGF.Builder.CreateExtractValue(Pair, 1); // This basic block is used to hold the store instruction if the operation // failed. diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index f705ed80c1..47245cf2d8 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -975,6 +975,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, Value *Result = Builder.CreateAtomicCmpXchg(Args[0], Args[1], Args[2], llvm::SequentiallyConsistent, llvm::SequentiallyConsistent); + Result = Builder.CreateExtractValue(Result, 0); Result = EmitFromInt(*this, Result, T, ValueType); return RValue::get(Result); } @@ -998,11 +999,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, Args[1] = EmitToInt(*this, EmitScalarExpr(E->getArg(1)), T, IntType); Args[2] = EmitToInt(*this, EmitScalarExpr(E->getArg(2)), T, IntType); - Value *OldVal = Args[1]; - Value *PrevVal = Builder.CreateAtomicCmpXchg(Args[0], Args[1], Args[2], - llvm::SequentiallyConsistent, - llvm::SequentiallyConsistent); - Value *Result = Builder.CreateICmpEQ(PrevVal, OldVal); + Value *Pair = Builder.CreateAtomicCmpXchg(Args[0], Args[1], Args[2], + llvm::SequentiallyConsistent, + llvm::SequentiallyConsistent); + Value *Result = Builder.CreateExtractValue(Pair, 1); // zext bool to int. Result = Builder.CreateZExt(Result, ConvertType(E->getType())); return RValue::get(Result); @@ -1524,7 +1524,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, SequentiallyConsistent, SequentiallyConsistent); CXI->setVolatile(true); - return RValue::get(CXI); + return RValue::get(Builder.CreateExtractValue(CXI, 0)); } case Builtin::BI_InterlockedIncrement: { AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 4dfa169615..14ef5b7982 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -1732,11 +1732,12 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, if (atomicPHI) { llvm::BasicBlock *opBB = Builder.GetInsertBlock(); llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn); - llvm::Value *old = Builder.CreateAtomicCmpXchg( + llvm::Value *pair = Builder.CreateAtomicCmpXchg( LV.getAddress(), atomicPHI, CGF.EmitToMemory(value, type), llvm::SequentiallyConsistent, llvm::SequentiallyConsistent); + llvm::Value *old = Builder.CreateExtractValue(pair, 0); + llvm::Value *success = Builder.CreateExtractValue(pair, 1); atomicPHI->addIncoming(old, opBB); - llvm::Value *success = Builder.CreateICmpEQ(old, atomicPHI); Builder.CreateCondBr(success, contBB, opBB); Builder.SetInsertPoint(contBB); return isPre ? value : input; @@ -2075,11 +2076,12 @@ LValue ScalarExprEmitter::EmitCompoundAssignLValue( if (atomicPHI) { llvm::BasicBlock *opBB = Builder.GetInsertBlock(); llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn); - llvm::Value *old = Builder.CreateAtomicCmpXchg( + llvm::Value *pair = Builder.CreateAtomicCmpXchg( LHSLV.getAddress(), atomicPHI, CGF.EmitToMemory(Result, LHSTy), llvm::SequentiallyConsistent, llvm::SequentiallyConsistent); + llvm::Value *old = Builder.CreateExtractValue(pair, 0); + llvm::Value *success = Builder.CreateExtractValue(pair, 1); atomicPHI->addIncoming(old, opBB); - llvm::Value *success = Builder.CreateICmpEQ(old, atomicPHI); Builder.CreateCondBr(success, contBB, opBB); Builder.SetInsertPoint(contBB); return LHSLV; diff --git a/test/CodeGen/Atomics.c b/test/CodeGen/Atomics.c index 5798dfff46..684f36d404 100644 --- a/test/CodeGen/Atomics.c +++ b/test/CodeGen/Atomics.c @@ -160,23 +160,70 @@ void test_op_and_fetch (void) void test_compare_and_swap (void) { - sc = __sync_val_compare_and_swap (&sc, uc, sc); // CHECK: cmpxchg i8 - uc = __sync_val_compare_and_swap (&uc, uc, sc); // CHECK: cmpxchg i8 - ss = __sync_val_compare_and_swap (&ss, uc, sc); // CHECK: cmpxchg i16 - us = __sync_val_compare_and_swap (&us, uc, sc); // CHECK: cmpxchg i16 - si = __sync_val_compare_and_swap (&si, uc, sc); // CHECK: cmpxchg i32 - ui = __sync_val_compare_and_swap (&ui, uc, sc); // CHECK: cmpxchg i32 - sll = __sync_val_compare_and_swap (&sll, uc, sc); // CHECK: cmpxchg i64 - ull = __sync_val_compare_and_swap (&ull, uc, sc); // CHECK: cmpxchg i64 - - ui = __sync_bool_compare_and_swap (&sc, uc, sc); // CHECK: cmpxchg - ui = __sync_bool_compare_and_swap (&uc, uc, sc); // CHECK: cmpxchg - ui = __sync_bool_compare_and_swap (&ss, uc, sc); // CHECK: cmpxchg - ui = __sync_bool_compare_and_swap (&us, uc, sc); // CHECK: cmpxchg - ui = __sync_bool_compare_and_swap (&si, uc, sc); // CHECK: cmpxchg - ui = __sync_bool_compare_and_swap (&ui, uc, sc); // CHECK: cmpxchg - ui = __sync_bool_compare_and_swap (&sll, uc, sc); // CHECK: cmpxchg - ui = __sync_bool_compare_and_swap (&ull, uc, sc); // CHECK: cmpxchg + sc = __sync_val_compare_and_swap (&sc, uc, sc); + // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i8 + // CHECK: extractvalue { i8, i1 } [[PAIR]], 0 + + uc = __sync_val_compare_and_swap (&uc, uc, sc); + // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i8 + // CHECK: extractvalue { i8, i1 } [[PAIR]], 0 + + ss = __sync_val_compare_and_swap (&ss, uc, sc); + // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i16 + // CHECK: extractvalue { i16, i1 } [[PAIR]], 0 + + us = __sync_val_compare_and_swap (&us, uc, sc); + // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i16 + // CHECK: extractvalue { i16, i1 } [[PAIR]], 0 + + si = __sync_val_compare_and_swap (&si, uc, sc); + // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i32 + // CHECK: extractvalue { i32, i1 } [[PAIR]], 0 + + ui = __sync_val_compare_and_swap (&ui, uc, sc); + // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i32 + // CHECK: extractvalue { i32, i1 } [[PAIR]], 0 + + sll = __sync_val_compare_and_swap (&sll, uc, sc); + // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i64 + // CHECK: extractvalue { i64, i1 } [[PAIR]], 0 + + ull = __sync_val_compare_and_swap (&ull, uc, sc); + // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i64 + // CHECK: extractvalue { i64, i1 } [[PAIR]], 0 + + + ui = __sync_bool_compare_and_swap (&sc, uc, sc); + // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i8 + // CHECK: extractvalue { i8, i1 } [[PAIR]], 1 + + ui = __sync_bool_compare_and_swap (&uc, uc, sc); + // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i8 + // CHECK: extractvalue { i8, i1 } [[PAIR]], 1 + + ui = __sync_bool_compare_and_swap (&ss, uc, sc); + // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i16 + // CHECK: extractvalue { i16, i1 } [[PAIR]], 1 + + ui = __sync_bool_compare_and_swap (&us, uc, sc); + // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i16 + // CHECK: extractvalue { i16, i1 } [[PAIR]], 1 + + ui = __sync_bool_compare_and_swap (&si, uc, sc); + // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i32 + // CHECK: extractvalue { i32, i1 } [[PAIR]], 1 + + ui = __sync_bool_compare_and_swap (&ui, uc, sc); + // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i32 + // CHECK: extractvalue { i32, i1 } [[PAIR]], 1 + + ui = __sync_bool_compare_and_swap (&sll, uc, sc); + // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i64 + // CHECK: extractvalue { i64, i1 } [[PAIR]], 1 + + ui = __sync_bool_compare_and_swap (&ull, uc, sc); + // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i64 + // CHECK: extractvalue { i64, i1 } [[PAIR]], 1 } void test_lock (void) diff --git a/test/CodeGen/atomic-ops.c b/test/CodeGen/atomic-ops.c index ddf2c76cc2..edcb63f90c 100644 --- a/test/CodeGen/atomic-ops.c +++ b/test/CodeGen/atomic-ops.c @@ -91,8 +91,9 @@ int fi3d(int *i) { _Bool fi4(_Atomic(int) *i) { // CHECK-LABEL: @fi4 - // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]] - // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = icmp eq i32 [[OLD]], [[EXPECTED]] + // CHECK: [[PAIR:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]] + // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 0 + // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 1 // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]] // CHECK: store i32 [[OLD]] int cmp = 0; @@ -101,8 +102,9 @@ _Bool fi4(_Atomic(int) *i) { _Bool fi4a(int *i) { // CHECK-LABEL: @fi4 - // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]] - // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = icmp eq i32 [[OLD]], [[EXPECTED]] + // CHECK: [[PAIR:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]] + // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 0 + // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 1 // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]] // CHECK: store i32 [[OLD]] int cmp = 0; @@ -112,8 +114,9 @@ _Bool fi4a(int *i) { _Bool fi4b(int *i) { // CHECK-LABEL: @fi4 - // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]] - // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = icmp eq i32 [[OLD]], [[EXPECTED]] + // CHECK: [[PAIR:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]] + // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 0 + // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 1 // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]] // CHECK: store i32 [[OLD]] int cmp = 0; diff --git a/test/CodeGen/atomic.c b/test/CodeGen/atomic.c index ac3848f02f..43f5bc81ee 100644 --- a/test/CodeGen/atomic.c +++ b/test/CodeGen/atomic.c @@ -35,10 +35,12 @@ int atomic(void) { // CHECK: atomicrmw xchg i32* %val, i32 8 seq_cst old = __sync_val_compare_and_swap(&val, 4, 1976); - // CHECK: cmpxchg i32* %val, i32 4, i32 1976 seq_cst - + // CHECK: [[PAIR:%[a-z0-9_.]+]] = cmpxchg i32* %val, i32 4, i32 1976 seq_cst + // CHECK: extractvalue { i32, i1 } [[PAIR]], 0 + old = __sync_bool_compare_and_swap(&val, 4, 1976); - // CHECK: cmpxchg i32* %val, i32 4, i32 1976 seq_cst + // CHECK: [[PAIR:%[a-z0-9_.]+]] = cmpxchg i32* %val, i32 4, i32 1976 seq_cst + // CHECK: extractvalue { i32, i1 } [[PAIR]], 1 old = __sync_fetch_and_and(&val, 0x9); // CHECK: atomicrmw and i32* %val, i32 9 seq_cst @@ -65,10 +67,13 @@ int atomic(void) { // CHECK: atomicrmw xor i8* %valc, i8 5 seq_cst __sync_val_compare_and_swap((void **)0, (void *)0, (void *)0); - // CHECK: cmpxchg i32* null, i32 0, i32 0 seq_cst + // CHECK: [[PAIR:%[a-z0-9_.]+]] = cmpxchg i32* null, i32 0, i32 0 seq_cst + // CHECK: extractvalue { i32, i1 } [[PAIR]], 0 if ( __sync_val_compare_and_swap(&valb, 0, 1)) { - // CHECK: cmpxchg i8* %valb, i8 0, i8 1 seq_cst + // CHECK: [[PAIR:%[a-z0-9_.]+]] = cmpxchg i8* %valb, i8 0, i8 1 seq_cst + // CHECK: [[VAL:%[a-z0-9_.]+]] = extractvalue { i8, i1 } [[PAIR]], 0 + // CHECK: trunc i8 [[VAL]] to i1 old = 42; }