[OpaquePtr][ValueTracking] Check GEP source element type in isPointerOffset()
authorArthur Eubanks <aeubanks@google.com>
Sun, 13 Feb 2022 01:37:20 +0000 (17:37 -0800)
committerArthur Eubanks <aeubanks@google.com>
Sun, 13 Feb 2022 18:35:38 +0000 (10:35 -0800)
Fixes a MemCpyOpt miscompile with opaque pointers.
This function can be further cleaned up, but let's just fix the miscompile first.

Reviewed By: #opaque-pointers, nikic

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

llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Transforms/MemCpyOpt/opaque-ptr.ll

index 236db5e..2fd4565 100644 (file)
@@ -7136,7 +7136,8 @@ Optional<int64_t> llvm::isPointerOffset(const Value *Ptr1, const Value *Ptr2,
   // potentially variable) indices.  After that they handle some constant
   // offset, which determines their offset from each other.  At this point, we
   // handle no other case.
-  if (!GEP1 || !GEP2 || GEP1->getOperand(0) != GEP2->getOperand(0))
+  if (!GEP1 || !GEP2 || GEP1->getOperand(0) != GEP2->getOperand(0) ||
+      GEP1->getSourceElementType() != GEP2->getSourceElementType())
     return None;
 
   // Skip any common indices and track the GEP types.
index 235addc..470775c 100644 (file)
@@ -22,6 +22,7 @@ define void @test_memset_memcpy(ptr %src, i64 %src_size, ptr noalias %dst, i64 %
 define void @test_different_gep_source_elements(ptr %src) {
 ; CHECK-LABEL: @test_different_gep_source_elements(
 ; CHECK-NEXT:    [[PB:%.*]] = getelementptr [[B:%.*]], ptr [[SRC:%.*]], i64 0, i32 1
+; CHECK-NEXT:    store i64 0, ptr [[PB]], align 4
 ; CHECK-NEXT:    [[PA:%.*]] = getelementptr [[A:%.*]], ptr [[SRC]], i64 0, i32 1
 ; CHECK-NEXT:    [[PA2:%.*]] = getelementptr [[A]], ptr [[SRC]], i64 0, i32 2
 ; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 4 [[PA]], i8 0, i64 16, i1 false)