]> granicus.if.org Git - clang/commitdiff
IR-change: cmpxchg operations now return { iN, i1 }.
authorTim Northover <tnorthover@apple.com>
Fri, 13 Jun 2014 14:24:59 +0000 (14:24 +0000)
committerTim Northover <tnorthover@apple.com>
Fri, 13 Jun 2014 14:24:59 +0000 (14:24 +0000)
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

lib/CodeGen/CGAtomic.cpp
lib/CodeGen/CGBuiltin.cpp
lib/CodeGen/CGExprScalar.cpp
test/CodeGen/Atomics.c
test/CodeGen/atomic-ops.c
test/CodeGen/atomic.c

index 18eb065226cb5f131727255fddf0ab9a51d0ad58..ad4ba88dc15871f84922e3b4e1244990b0e7decd 100644 (file)
@@ -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.
index f705ed80c14cd49052b8ddd9d7bcc2634dfc74ff..47245cf2d8302e7a68cc4d88439ac4911f0f67ed 100644 (file)
@@ -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(
index 4dfa16961580ff4ceefd386d969df3159f608ed1..14ef5b7982649bcd38df1abe0d25a96c4bd6f8a8 100644 (file)
@@ -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;
index 5798dfff46b1073e8d53467c346c3fe7bfc0bad6..684f36d404401df84d3a3d37255c020975ddf982 100644 (file)
@@ -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)
index ddf2c76cc24318853f2007981759f7e48f3f4102..edcb63f90cc568adc1c21160cb1be0f66cc67b26 100644 (file)
@@ -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;
index ac3848f02f9e683fe3e5e1be8f819a1c89fbd00c..43f5bc81ee984068db065016000f3935f7eb0523 100644 (file)
@@ -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;
   }