forked from OSchip/llvm-project
[DSE] Support opaque pointers
For the start shortening optimization, always use a i8 type for the GEP, as it is a raw offset calculation. Handling of non-i8* memset/memcpy arguments requires insertion of casts. These cases were previously miscompiled, as the offset calculation was performed on the wrong type.
This commit is contained in:
parent
09ac97ce35
commit
f00941e061
|
@ -642,12 +642,20 @@ static bool tryToShorten(Instruction *EarlierWrite, int64_t &EarlierStart,
|
|||
EarlierIntrinsic->setDestAlignment(PrefAlign);
|
||||
|
||||
if (!IsOverwriteEnd) {
|
||||
Type *Int8PtrTy = Type::getInt8PtrTy(EarlierIntrinsic->getContext());
|
||||
Value *OrigDest = EarlierIntrinsic->getRawDest();
|
||||
Value *Dest = OrigDest;
|
||||
if (OrigDest->getType() != Int8PtrTy)
|
||||
Dest = CastInst::CreatePointerCast(OrigDest, Int8PtrTy, "", EarlierWrite);
|
||||
Value *Indices[1] = {
|
||||
ConstantInt::get(EarlierWriteLength->getType(), ToRemoveSize)};
|
||||
GetElementPtrInst *NewDestGEP = GetElementPtrInst::CreateInBounds(
|
||||
EarlierIntrinsic->getRawDest()->getType()->getPointerElementType(),
|
||||
EarlierIntrinsic->getRawDest(), Indices, "", EarlierWrite);
|
||||
Instruction *NewDestGEP = GetElementPtrInst::CreateInBounds(
|
||||
Type::getInt8Ty(EarlierIntrinsic->getContext()),
|
||||
Dest, Indices, "", EarlierWrite);
|
||||
NewDestGEP->setDebugLoc(EarlierIntrinsic->getDebugLoc());
|
||||
if (NewDestGEP->getType() != OrigDest->getType())
|
||||
NewDestGEP = CastInst::CreatePointerCast(NewDestGEP, OrigDest->getType(),
|
||||
"", EarlierWrite);
|
||||
EarlierIntrinsic->setDest(NewDestGEP);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,46 @@ entry:
|
|||
ret void
|
||||
}
|
||||
|
||||
define void @write4to7_opaque_ptr(ptr nocapture %p) {
|
||||
; CHECK-LABEL: @write4to7_opaque_ptr(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = bitcast ptr [[ARRAYIDX0]] to i8*
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[TMP0]], i64 4
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to ptr
|
||||
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP2]], i8 0, i64 24, i1 false)
|
||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 1
|
||||
; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX1]], align 4
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
%arrayidx0 = getelementptr inbounds i32, ptr %p, i64 1
|
||||
call void @llvm.memset.p0.i64(ptr align 4 %arrayidx0, i8 0, i64 28, i1 false)
|
||||
%arrayidx1 = getelementptr inbounds i32, ptr %p, i64 1
|
||||
store i32 1, ptr %arrayidx1, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @write4to7_weird_element_type(i32* nocapture %p) {
|
||||
; CHECK-LABEL: @write4to7_weird_element_type(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[TMP0]], i64 4
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
|
||||
; CHECK-NEXT: call void @llvm.memset.p0i32.i64(i32* align 4 [[TMP2]], i8 0, i64 24, i1 false)
|
||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
|
||||
; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX1]], align 4
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
%arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
|
||||
call void @llvm.memset.p0i32.i64(i32* align 4 %arrayidx0, i8 0, i64 28, i1 false)
|
||||
%arrayidx1 = getelementptr inbounds i32, i32* %p, i64 1
|
||||
store i32 1, i32* %arrayidx1, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @write4to7_atomic(i32* nocapture %p) {
|
||||
; CHECK-LABEL: @write4to7_atomic(
|
||||
; CHECK-NEXT: entry:
|
||||
|
@ -291,8 +331,8 @@ define void @write8To15AndThen0To7(i64* nocapture %P) {
|
|||
; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* align 8 [[TMP0]], i8 0, i64 16, i1 false)
|
||||
; CHECK-NEXT: [[BASE64_0:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 0
|
||||
; CHECK-NEXT: [[BASE64_1:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 1
|
||||
; CHECK-NEXT: store i64 1, i64* [[BASE64_1]]
|
||||
; CHECK-NEXT: store i64 2, i64* [[BASE64_0]]
|
||||
; CHECK-NEXT: store i64 1, i64* [[BASE64_1]], align 4
|
||||
; CHECK-NEXT: store i64 2, i64* [[BASE64_0]], align 4
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
|
@ -391,6 +431,8 @@ entry:
|
|||
}
|
||||
|
||||
declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
|
||||
declare void @llvm.memset.p0i32.i64(i32* nocapture, i8, i64, i1) nounwind
|
||||
declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1) nounwind
|
||||
declare void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* nocapture, i8, i64, i32) nounwind
|
||||
|
||||
define void @ow_begin_align1(i8* nocapture %p) {
|
||||
|
|
Loading…
Reference in New Issue