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. llvm-svn: 210907
This commit is contained in:
parent
d7756c5a68
commit
b49b04bbe0
|
@ -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.
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
sc = __sync_val_compare_and_swap (&sc, uc, sc);
|
||||
// CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i8
|
||||
// CHECK: extractvalue { i8, i1 } [[PAIR]], 0
|
||||
|
||||
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
|
||||
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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue