[llvm] 1b25fce - [OpaquePtr] Make cmpxchg work with opaque pointers

Arthur Eubanks via llvm-commits llvm-commits at lists.llvm.org
Wed May 19 12:44:27 PDT 2021


Author: Arthur Eubanks
Date: 2021-05-19T12:44:10-07:00
New Revision: 1b25fce404d40c6c6358037104e1e3c3aedb60ef

URL: https://github.com/llvm/llvm-project/commit/1b25fce404d40c6c6358037104e1e3c3aedb60ef
DIFF: https://github.com/llvm/llvm-project/commit/1b25fce404d40c6c6358037104e1e3c3aedb60ef.diff

LOG: [OpaquePtr] Make cmpxchg work with opaque pointers

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D102745

Added: 
    llvm/test/Assembler/opaque-ptr-cmpxchg.ll

Modified: 
    llvm/lib/AsmParser/LLParser.cpp
    llvm/lib/IR/Instructions.cpp
    llvm/lib/IR/Verifier.cpp
    llvm/test/Assembler/opaque-ptr.ll
    llvm/test/Verifier/opaque-ptr.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index a4bb423a94233..21bd89776c414 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -7591,10 +7591,14 @@ int LLParser::parseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) {
         "cmpxchg failure ordering cannot include release semantics");
   if (!Ptr->getType()->isPointerTy())
     return error(PtrLoc, "cmpxchg operand must be a pointer");
-  if (cast<PointerType>(Ptr->getType())->getElementType() != Cmp->getType())
+  if (!cast<PointerType>(Ptr->getType())
+           ->isOpaqueOrPointeeTypeMatches(Cmp->getType()))
     return error(CmpLoc, "compare value and pointer type do not match");
-  if (cast<PointerType>(Ptr->getType())->getElementType() != New->getType())
+  if (!cast<PointerType>(Ptr->getType())
+           ->isOpaqueOrPointeeTypeMatches(New->getType()))
     return error(NewLoc, "new value and pointer type do not match");
+  if (Cmp->getType() != New->getType())
+    return error(NewLoc, "compare value and new value type do not match");
   if (!New->getType()->isFirstClassType())
     return error(NewLoc, "cmpxchg operand must be a first class value");
 

diff  --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index 134a023f81d93..e3691c174afc8 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -1548,12 +1548,14 @@ void AtomicCmpXchgInst::Init(Value *Ptr, Value *Cmp, Value *NewVal,
          "All operands must be non-null!");
   assert(getOperand(0)->getType()->isPointerTy() &&
          "Ptr must have pointer type!");
-  assert(getOperand(1)->getType() ==
-                 cast<PointerType>(getOperand(0)->getType())->getElementType()
-         && "Ptr must be a pointer to Cmp type!");
-  assert(getOperand(2)->getType() ==
-                 cast<PointerType>(getOperand(0)->getType())->getElementType()
-         && "Ptr must be a pointer to NewVal type!");
+  assert(cast<PointerType>(getOperand(0)->getType())
+             ->isOpaqueOrPointeeTypeMatches(getOperand(1)->getType()) &&
+         "Ptr must be a pointer to Cmp type!");
+  assert(cast<PointerType>(getOperand(0)->getType())
+             ->isOpaqueOrPointeeTypeMatches(getOperand(2)->getType()) &&
+         "Ptr must be a pointer to NewVal type!");
+  assert(getOperand(1)->getType() == getOperand(2)->getType() &&
+         "Cmp type and NewVal type must be same!");
   assert(SuccessOrdering != AtomicOrdering::NotAtomic &&
          "AtomicCmpXchg instructions must be atomic!");
   assert(FailureOrdering != AtomicOrdering::NotAtomic &&

diff  --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 986d7ec10a812..adb6ab70e8315 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -3847,15 +3847,16 @@ void Verifier::visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI) {
 
   PointerType *PTy = dyn_cast<PointerType>(CXI.getOperand(0)->getType());
   Assert(PTy, "First cmpxchg operand must be a pointer.", &CXI);
-  Type *ElTy = PTy->getElementType();
-  Assert(ElTy->isIntOrPtrTy(),
-         "cmpxchg operand must have integer or pointer type", ElTy, &CXI);
-  checkAtomicMemAccessSize(ElTy, &CXI);
-  Assert(ElTy == CXI.getOperand(1)->getType(),
+  Type *ElTy = CXI.getOperand(1)->getType();
+  Assert(PTy->isOpaqueOrPointeeTypeMatches(ElTy),
          "Expected value type does not match pointer operand type!", &CXI,
          ElTy);
   Assert(ElTy == CXI.getOperand(2)->getType(),
-         "Stored value type does not match pointer operand type!", &CXI, ElTy);
+         "Stored value type does not match expected value operand type!", &CXI,
+         ElTy);
+  Assert(ElTy->isIntOrPtrTy(),
+         "cmpxchg operand must have integer or pointer type", ElTy, &CXI);
+  checkAtomicMemAccessSize(ElTy, &CXI);
   visitInstruction(CXI);
 }
 

diff  --git a/llvm/test/Assembler/opaque-ptr-cmpxchg.ll b/llvm/test/Assembler/opaque-ptr-cmpxchg.ll
new file mode 100644
index 0000000000000..ad581ffc36ac0
--- /dev/null
+++ b/llvm/test/Assembler/opaque-ptr-cmpxchg.ll
@@ -0,0 +1,7 @@
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+
+; CHECK: compare value and new value type do not match
+define void @cmpxchg(ptr %p, i32 %a, i64 %b) {
+    %val_success = cmpxchg ptr %p, i32 %a, i64 %b acq_rel monotonic
+    ret void
+}

diff  --git a/llvm/test/Assembler/opaque-ptr.ll b/llvm/test/Assembler/opaque-ptr.ll
index 1fb0c5da8eafd..86ff1cd5d9299 100644
--- a/llvm/test/Assembler/opaque-ptr.ll
+++ b/llvm/test/Assembler/opaque-ptr.ll
@@ -48,3 +48,11 @@ define void @gep(ptr %a) {
     %b = getelementptr i8, ptr %a, i32 2
     ret void
 }
+
+; CHECK: define void @cmpxchg(ptr %p, i32 %a, i32 %b)
+; CHECK:     %val_success = cmpxchg ptr %p, i32 %a, i32 %b acq_rel monotonic
+; CHECK:     ret void
+define void @cmpxchg(ptr %p, i32 %a, i32 %b) {
+    %val_success = cmpxchg ptr %p, i32 %a, i32 %b acq_rel monotonic
+    ret void
+}

diff  --git a/llvm/test/Verifier/opaque-ptr.ll b/llvm/test/Verifier/opaque-ptr.ll
index ff25a8c940fd4..1fd1b3a8a1715 100644
--- a/llvm/test/Verifier/opaque-ptr.ll
+++ b/llvm/test/Verifier/opaque-ptr.ll
@@ -11,3 +11,9 @@ define void @store(ptr %a, i32 %i) {
     store i32 %i, ptr %a
     ret void
 }
+
+; CHECK: @cmpxchg
+define void @cmpxchg(ptr %p, i32 %a, i32 %b) {
+    %val_success = cmpxchg ptr %p, i32 %a, i32 %b acq_rel monotonic
+    ret void
+}


        


More information about the llvm-commits mailing list