From a9029a33ffe5cd458b51b18f7faf5d1c844f4bb4 Mon Sep 17 00:00:00 2001 From: Arthur Eubanks Date: Sat, 12 Feb 2022 17:37:20 -0800 Subject: [PATCH] [OpaquePtr][ValueTracking] Check GEP source element type in isPointerOffset() 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 | 3 ++- llvm/test/Transforms/MemCpyOpt/opaque-ptr.ll | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 236db5e..2fd4565 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -7136,7 +7136,8 @@ Optional 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. diff --git a/llvm/test/Transforms/MemCpyOpt/opaque-ptr.ll b/llvm/test/Transforms/MemCpyOpt/opaque-ptr.ll index 235addc..470775c 100644 --- a/llvm/test/Transforms/MemCpyOpt/opaque-ptr.ll +++ b/llvm/test/Transforms/MemCpyOpt/opaque-ptr.ll @@ -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) -- 2.7.4