forked from OSchip/llvm-project
[InstCombine] Transform to undef incorrect atomic unordered mem intrinsics
According to LangRef: If len is not a positive integer multiple of element_size, then the behaviour of the intrinsic is undefined. Add InstCombine rule to transform intrinsic to undef operation. This is a follow-up for D76116. Reviewers: reames Reviewed By: reames Subscribers: hiraditya, jfb, dantrushin, llvm-commits Differential Revision: https://reviews.llvm.org/D76215
This commit is contained in:
parent
fa72b29bec
commit
80c351cdb6
|
@ -1806,6 +1806,18 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
|||
IntrinsicInst *II = dyn_cast<IntrinsicInst>(&CI);
|
||||
if (!II) return visitCallBase(CI);
|
||||
|
||||
// For atomic unordered mem intrinsics if len is not a positive or
|
||||
// not a multiple of element size then behavior is undefined.
|
||||
if (auto *AMI = dyn_cast<AtomicMemIntrinsic>(II))
|
||||
if (ConstantInt *NumBytes = dyn_cast<ConstantInt>(AMI->getLength()))
|
||||
if (NumBytes->getSExtValue() < 0 ||
|
||||
(NumBytes->getZExtValue() % AMI->getElementSizeInBytes() != 0)) {
|
||||
CreateNonTerminatorUnreachable(AMI);
|
||||
assert(AMI->getType()->isVoidTy() &&
|
||||
"non void atomic unordered mem intrinsic");
|
||||
return eraseInstFromFunction(*AMI);
|
||||
}
|
||||
|
||||
// Intrinsics cannot occur in an invoke or a callbr, so handle them here
|
||||
// instead of in visitCallBase.
|
||||
if (auto *MI = dyn_cast<AnyMemIntrinsic>(II)) {
|
||||
|
|
|
@ -415,4 +415,23 @@ define void @test_memcpy_loadstore_16(i8* %dest, i8* %src) {
|
|||
ret void
|
||||
}
|
||||
|
||||
define void @test_undefined(i8* %dest, i8* %src) {
|
||||
; CHECK-LABEL: @test_undefined(
|
||||
entry:
|
||||
br i1 undef, label %ok, label %undefined
|
||||
undefined:
|
||||
; CHECK: undefined:
|
||||
; CHECK-NEXT: store i1 true, i1* undef
|
||||
; CHECK-NEXT: br label %ok
|
||||
call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i32(i8* align 16 %dest, i8* align 16 %src, i32 7, i32 4)
|
||||
call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i32(i8* align 16 %dest, i8* align 16 %src, i32 -8, i32 4)
|
||||
call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i32(i8* align 16 %dest, i8* align 16 %src, i32 7, i32 4)
|
||||
call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i32(i8* align 16 %dest, i8* align 16 %src, i32 -8, i32 4)
|
||||
call void @llvm.memset.element.unordered.atomic.p0i8.i32(i8* align 16 %dest, i8 1, i32 7, i32 4)
|
||||
call void @llvm.memset.element.unordered.atomic.p0i8.i32(i8* align 16 %dest, i8 1, i32 -8, i32 4)
|
||||
br label %ok
|
||||
ok:
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i32(i8* nocapture writeonly, i8* nocapture readonly, i32, i32) nounwind argmemonly
|
||||
|
|
Loading…
Reference in New Issue