[PATCH] D88995: Support vectors in CastInst::isBitOrNoopPointerCastable

Philip Reames via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 7 11:43:21 PDT 2020


reames created this revision.
reames added reviewers: vtjnash, lebedev.ri.
Herald added subscribers: dantrushin, bollu, hiraditya, mcrosier.
Herald added a project: LLVM.
reames requested review of this revision.

Add support for vectors to this utility function.  As noted in the diffs, this utility is used in several transforms so adding the generic logic gets picked up in several places.

The LangRef wording is rather vague here, but you can see analogous logic in VNCoercion.cpp and the Verifier's rules for inttoptr/ptrtoint.

Note that the isNoopCast function is currently incorrect for vectors.  I plan on fixing that in a follow up, and then trying to merge the code paths.  (Before this change, isBitOrNoopPointerCastable was merely incomplete, not incorrect.)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D88995

Files:
  llvm/lib/IR/Instructions.cpp
  llvm/test/Transforms/InstCombine/call.ll
  llvm/test/Transforms/InstCombine/load.ll


Index: llvm/test/Transforms/InstCombine/load.ll
===================================================================
--- llvm/test/Transforms/InstCombine/load.ll
+++ llvm/test/Transforms/InstCombine/load.ll
@@ -385,10 +385,9 @@
 
 define <2 x i64> @test23(<2 x i64>* %P) {
 ; CHECK-LABEL: @test23(
-; CHECK-NEXT:    [[P_PTR:%.*]] = bitcast <2 x i64>* [[P:%.*]] to <2 x i8*>*
-; CHECK-NEXT:    [[X:%.*]] = load <2 x i64>, <2 x i64>* [[P]], align 16
-; CHECK-NEXT:    [[Y:%.*]] = load <2 x i8*>, <2 x i8*>* [[P_PTR]], align 16
-; CHECK-NEXT:    call void @use.v2.p0(<2 x i8*> [[Y]])
+; CHECK-NEXT:    [[X:%.*]] = load <2 x i64>, <2 x i64>* [[P:%.*]], align 16
+; CHECK-NEXT:    [[Y_CAST:%.*]] = inttoptr <2 x i64> [[X]] to <2 x i8*>
+; CHECK-NEXT:    call void @use.v2.p0(<2 x i8*> [[Y_CAST]])
 ; CHECK-NEXT:    ret <2 x i64> [[X]]
 ;
   %P.ptr = bitcast <2 x i64>* %P to <2 x i8*>*
Index: llvm/test/Transforms/InstCombine/call.ll
===================================================================
--- llvm/test/Transforms/InstCombine/call.ll
+++ llvm/test/Transforms/InstCombine/call.ll
@@ -235,7 +235,7 @@
 
 define void @test13(<2 x i32*> %A) {
 ; CHECK-LABEL: @test13(
-; CHECK: call void bitcast
+; CHECK: call void @test13a
   call void bitcast (void (<2 x i64>)* @test13a to void (<2 x i32*>)*)(<2 x i32*> %A)
   ret void
 }
@@ -246,7 +246,7 @@
 
 define void @test14(<2 x i64> %A) {
 ; CHECK-LABEL: @test14(
-; CHECK: call void bitcast
+; CHECK: call void @test14a
   call void bitcast (void (<2 x i8*>)* @test14a to void (<2 x i64>)*)(<2 x i64> %A)
   ret void
 }
Index: llvm/lib/IR/Instructions.cpp
===================================================================
--- llvm/lib/IR/Instructions.cpp
+++ llvm/lib/IR/Instructions.cpp
@@ -3226,8 +3226,22 @@
   return true;
 }
 
-bool CastInst::isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy,
-                                          const DataLayout &DL) {
+/// Return true if conversion is valid with an inttoptr/ptrtoint.  Note that
+/// the results are expected to match CastInst::isNoopCast, but we can't use
+/// that directly since it doesn't check preconditions.
+static bool isNoopPointerCastable(Type *SrcTy, Type *DestTy,
+                                  const DataLayout &DL) {
+
+  if (VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy)) {
+    if (VectorType *DestVecTy = dyn_cast<VectorType>(DestTy)) {
+      if (SrcVecTy->getElementCount() == DestVecTy->getElementCount()) {
+        // An element by element cast. Valid if casting the elements is valid.
+        SrcTy = SrcVecTy->getElementType();
+        DestTy = DestVecTy->getElementType();
+      }
+    }
+  }
+  
   // ptrtoint and inttoptr are not allowed on non-integral pointers
   if (auto *PtrTy = dyn_cast<PointerType>(SrcTy))
     if (auto *IntTy = dyn_cast<IntegerType>(DestTy))
@@ -3238,6 +3252,14 @@
       return (IntTy->getBitWidth() == DL.getPointerTypeSizeInBits(PtrTy) &&
               !DL.isNonIntegralPointerType(PtrTy));
 
+  return false;
+}
+  
+bool CastInst::isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy,
+                                          const DataLayout &DL) {
+
+  if (isNoopPointerCastable(SrcTy, DestTy, DL))
+    return true;
   return isBitCastable(SrcTy, DestTy);
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D88995.296757.patch
Type: text/x-patch
Size: 3259 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201007/5d98603d/attachment-0001.bin>


More information about the llvm-commits mailing list