forked from OSchip/llvm-project
[DSE] Convert tests to opaque pointers (NFC)
Using https://gist.github.com/nikic/98357b71fd67756b0f064c9517b62a34.
This commit is contained in:
parent
20c9ac2925
commit
c603cefbda
|
@ -5,19 +5,17 @@ target triple = "i386-apple-darwin9.8"
|
||||||
|
|
||||||
@A = external global [0 x i32]
|
@A = external global [0 x i32]
|
||||||
|
|
||||||
declare ghccc void @Func2(i32*, i32*, i32*, i32)
|
declare ghccc void @Func2(ptr, ptr, ptr, i32)
|
||||||
|
|
||||||
define ghccc void @Func1(i32* noalias %Arg1, i32* noalias %Arg2, i32* %Arg3, i32 %Arg4) {
|
define ghccc void @Func1(ptr noalias %Arg1, ptr noalias %Arg2, ptr %Arg3, i32 %Arg4) {
|
||||||
entry:
|
entry:
|
||||||
store i32 add (i32 ptrtoint ([0 x i32]* @A to i32), i32 1), i32* %Arg2
|
store i32 add (i32 ptrtoint (ptr @A to i32), i32 1), ptr %Arg2
|
||||||
; CHECK: store i32 add (i32 ptrtoint ([0 x i32]* @A to i32), i32 1), i32* %Arg2
|
; CHECK: store i32 add (i32 ptrtoint (ptr @A to i32), i32 1), ptr %Arg2
|
||||||
%ln2gz = getelementptr i32, i32* %Arg1, i32 14
|
%ln2gz = getelementptr i32, ptr %Arg1, i32 14
|
||||||
%ln2gA = bitcast i32* %ln2gz to double*
|
%ln2gB = load double, ptr %ln2gz
|
||||||
%ln2gB = load double, double* %ln2gA
|
%ln2gD = getelementptr i32, ptr %Arg2, i32 -3
|
||||||
%ln2gD = getelementptr i32, i32* %Arg2, i32 -3
|
store double %ln2gB, ptr %ln2gD
|
||||||
%ln2gE = bitcast i32* %ln2gD to double*
|
; CHECK: store double %ln2gB, ptr %ln2gD
|
||||||
store double %ln2gB, double* %ln2gE
|
tail call ghccc void @Func2(ptr %Arg1, ptr %Arg2, ptr %Arg3, i32 %Arg4) nounwind
|
||||||
; CHECK: store double %ln2gB, double* %ln2gE
|
|
||||||
tail call ghccc void @Func2(i32* %Arg1, i32* %Arg2, i32* %Arg3, i32 %Arg4) nounwind
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,21 +3,19 @@
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||||
target triple = "x86_64-apple-darwin"
|
target triple = "x86_64-apple-darwin"
|
||||||
|
|
||||||
%"class.std::auto_ptr" = type { i32* }
|
%"class.std::auto_ptr" = type { ptr }
|
||||||
|
|
||||||
; CHECK-LABEL: @_Z3foov(
|
; CHECK-LABEL: @_Z3foov(
|
||||||
define void @_Z3foov(%"class.std::auto_ptr"* noalias nocapture sret(%"class.std::auto_ptr") %agg.result) uwtable ssp {
|
define void @_Z3foov(ptr noalias nocapture sret(%"class.std::auto_ptr") %agg.result) uwtable ssp {
|
||||||
_ZNSt8auto_ptrIiED1Ev.exit:
|
_ZNSt8auto_ptrIiED1Ev.exit:
|
||||||
%temp.lvalue = alloca %"class.std::auto_ptr", align 8
|
%temp.lvalue = alloca %"class.std::auto_ptr", align 8
|
||||||
call void @_Z3barv(%"class.std::auto_ptr"* sret(%"class.std::auto_ptr") %temp.lvalue)
|
call void @_Z3barv(ptr sret(%"class.std::auto_ptr") %temp.lvalue)
|
||||||
%_M_ptr.i.i = getelementptr inbounds %"class.std::auto_ptr", %"class.std::auto_ptr"* %temp.lvalue, i64 0, i32 0
|
%tmp.i.i = load ptr, ptr %temp.lvalue, align 8
|
||||||
%tmp.i.i = load i32*, i32** %_M_ptr.i.i, align 8
|
; CHECK-NOT: store ptr null
|
||||||
; CHECK-NOT: store i32* null
|
store ptr null, ptr %temp.lvalue, align 8
|
||||||
store i32* null, i32** %_M_ptr.i.i, align 8
|
store ptr %tmp.i.i, ptr %agg.result, align 8
|
||||||
%_M_ptr.i.i4 = getelementptr inbounds %"class.std::auto_ptr", %"class.std::auto_ptr"* %agg.result, i64 0, i32 0
|
|
||||||
store i32* %tmp.i.i, i32** %_M_ptr.i.i4, align 8
|
|
||||||
; CHECK: ret void
|
; CHECK: ret void
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @_Z3barv(%"class.std::auto_ptr"* sret(%"class.std::auto_ptr"))
|
declare void @_Z3barv(ptr sret(%"class.std::auto_ptr"))
|
||||||
|
|
|
@ -2,84 +2,79 @@
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-f128:128:128-n8:16:32:64"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-f128:128:128-n8:16:32:64"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
||||||
%struct.pair.162 = type { %struct.BasicBlock*, i32, [4 x i8] }
|
%struct.pair.162 = type { ptr, i32, [4 x i8] }
|
||||||
%struct.BasicBlock = type { %struct.Value, %struct.ilist_node.24, %struct.iplist.22, %struct.Function* }
|
%struct.BasicBlock = type { %struct.Value, %struct.ilist_node.24, %struct.iplist.22, ptr }
|
||||||
%struct.Value = type { i32 (...)**, i8, i8, i16, %struct.Type*, %struct.Use*, %struct.StringMapEntry* }
|
%struct.Value = type { ptr, i8, i8, i16, ptr, ptr, ptr }
|
||||||
%struct.Type = type { %struct.LLVMContext*, i8, [3 x i8], i32, {}* }
|
%struct.Type = type { ptr, i8, [3 x i8], i32, ptr }
|
||||||
%struct.LLVMContext = type { %struct.LLVMContextImpl* }
|
%struct.LLVMContext = type { ptr }
|
||||||
%struct.LLVMContextImpl = type opaque
|
%struct.LLVMContextImpl = type opaque
|
||||||
%struct.Use = type { %struct.Value*, %struct.Use*, %struct.PointerIntPair }
|
%struct.Use = type { ptr, ptr, %struct.PointerIntPair }
|
||||||
%struct.PointerIntPair = type { i64 }
|
%struct.PointerIntPair = type { i64 }
|
||||||
%struct.StringMapEntry = type opaque
|
%struct.StringMapEntry = type opaque
|
||||||
%struct.ilist_node.24 = type { %struct.ilist_half_node.23, %struct.BasicBlock* }
|
%struct.ilist_node.24 = type { %struct.ilist_half_node.23, ptr }
|
||||||
%struct.ilist_half_node.23 = type { %struct.BasicBlock* }
|
%struct.ilist_half_node.23 = type { ptr }
|
||||||
%struct.iplist.22 = type { %struct.ilist_traits.21, %struct.Instruction* }
|
%struct.iplist.22 = type { %struct.ilist_traits.21, ptr }
|
||||||
%struct.ilist_traits.21 = type { %struct.ilist_half_node.25 }
|
%struct.ilist_traits.21 = type { %struct.ilist_half_node.25 }
|
||||||
%struct.ilist_half_node.25 = type { %struct.Instruction* }
|
%struct.ilist_half_node.25 = type { ptr }
|
||||||
%struct.Instruction = type { [52 x i8], %struct.ilist_node.26, %struct.BasicBlock*, %struct.DebugLoc }
|
%struct.Instruction = type { [52 x i8], %struct.ilist_node.26, ptr, %struct.DebugLoc }
|
||||||
%struct.ilist_node.26 = type { %struct.ilist_half_node.25, %struct.Instruction* }
|
%struct.ilist_node.26 = type { %struct.ilist_half_node.25, ptr }
|
||||||
%struct.DebugLoc = type { i32, i32 }
|
%struct.DebugLoc = type { i32, i32 }
|
||||||
%struct.Function = type { %struct.GlobalValue, %struct.ilist_node.14, %struct.iplist.4, %struct.iplist, %struct.ValueSymbolTable*, %struct.AttrListPtr }
|
%struct.Function = type { %struct.GlobalValue, %struct.ilist_node.14, %struct.iplist.4, %struct.iplist, ptr, %struct.AttrListPtr }
|
||||||
%struct.GlobalValue = type <{ [52 x i8], [4 x i8], %struct.Module*, i8, i16, [5 x i8], %struct.basic_string }>
|
%struct.GlobalValue = type <{ [52 x i8], [4 x i8], ptr, i8, i16, [5 x i8], %struct.basic_string }>
|
||||||
%struct.Module = type { %struct.LLVMContext*, %struct.iplist.20, %struct.iplist.16, %struct.iplist.12, %struct.vector.2, %struct.ilist, %struct.basic_string, %struct.ValueSymbolTable*, %struct.OwningPtr, %struct.basic_string, %struct.basic_string, %struct.basic_string, i8* }
|
%struct.Module = type { ptr, %struct.iplist.20, %struct.iplist.16, %struct.iplist.12, %struct.vector.2, %struct.ilist, %struct.basic_string, ptr, %struct.OwningPtr, %struct.basic_string, %struct.basic_string, %struct.basic_string, ptr }
|
||||||
%struct.iplist.20 = type { %struct.ilist_traits.19, %struct.GlobalVariable* }
|
%struct.iplist.20 = type { %struct.ilist_traits.19, ptr }
|
||||||
%struct.ilist_traits.19 = type { %struct.ilist_node.18 }
|
%struct.ilist_traits.19 = type { %struct.ilist_node.18 }
|
||||||
%struct.ilist_node.18 = type { %struct.ilist_half_node.17, %struct.GlobalVariable* }
|
%struct.ilist_node.18 = type { %struct.ilist_half_node.17, ptr }
|
||||||
%struct.ilist_half_node.17 = type { %struct.GlobalVariable* }
|
%struct.ilist_half_node.17 = type { ptr }
|
||||||
%struct.GlobalVariable = type { %struct.GlobalValue, %struct.ilist_node.18, i8, [7 x i8] }
|
%struct.GlobalVariable = type { %struct.GlobalValue, %struct.ilist_node.18, i8, [7 x i8] }
|
||||||
%struct.iplist.16 = type { %struct.ilist_traits.15, %struct.Function* }
|
%struct.iplist.16 = type { %struct.ilist_traits.15, ptr }
|
||||||
%struct.ilist_traits.15 = type { %struct.ilist_node.14 }
|
%struct.ilist_traits.15 = type { %struct.ilist_node.14 }
|
||||||
%struct.ilist_node.14 = type { %struct.ilist_half_node.13, %struct.Function* }
|
%struct.ilist_node.14 = type { %struct.ilist_half_node.13, ptr }
|
||||||
%struct.ilist_half_node.13 = type { %struct.Function* }
|
%struct.ilist_half_node.13 = type { ptr }
|
||||||
%struct.iplist.12 = type { %struct.ilist_traits.11, %struct.GlobalAlias* }
|
%struct.iplist.12 = type { %struct.ilist_traits.11, ptr }
|
||||||
%struct.ilist_traits.11 = type { %struct.ilist_node.10 }
|
%struct.ilist_traits.11 = type { %struct.ilist_node.10 }
|
||||||
%struct.ilist_node.10 = type { %struct.ilist_half_node.9, %struct.GlobalAlias* }
|
%struct.ilist_node.10 = type { %struct.ilist_half_node.9, ptr }
|
||||||
%struct.ilist_half_node.9 = type { %struct.GlobalAlias* }
|
%struct.ilist_half_node.9 = type { ptr }
|
||||||
%struct.GlobalAlias = type { %struct.GlobalValue, %struct.ilist_node.10 }
|
%struct.GlobalAlias = type { %struct.GlobalValue, %struct.ilist_node.10 }
|
||||||
%struct.vector.2 = type { %struct._Vector_base.1 }
|
%struct.vector.2 = type { %struct._Vector_base.1 }
|
||||||
%struct._Vector_base.1 = type { %struct._Vector_impl.0 }
|
%struct._Vector_base.1 = type { %struct._Vector_impl.0 }
|
||||||
%struct._Vector_impl.0 = type { %struct.basic_string*, %struct.basic_string*, %struct.basic_string* }
|
%struct._Vector_impl.0 = type { ptr, ptr, ptr }
|
||||||
%struct.basic_string = type { %struct._Alloc_hider }
|
%struct.basic_string = type { %struct._Alloc_hider }
|
||||||
%struct._Alloc_hider = type { i8* }
|
%struct._Alloc_hider = type { ptr }
|
||||||
%struct.ilist = type { %struct.iplist.8 }
|
%struct.ilist = type { %struct.iplist.8 }
|
||||||
%struct.iplist.8 = type { %struct.ilist_traits.7, %struct.NamedMDNode* }
|
%struct.iplist.8 = type { %struct.ilist_traits.7, ptr }
|
||||||
%struct.ilist_traits.7 = type { %struct.ilist_node.6 }
|
%struct.ilist_traits.7 = type { %struct.ilist_node.6 }
|
||||||
%struct.ilist_node.6 = type { %struct.ilist_half_node.5, %struct.NamedMDNode* }
|
%struct.ilist_node.6 = type { %struct.ilist_half_node.5, ptr }
|
||||||
%struct.ilist_half_node.5 = type { %struct.NamedMDNode* }
|
%struct.ilist_half_node.5 = type { ptr }
|
||||||
%struct.NamedMDNode = type { %struct.ilist_node.6, %struct.basic_string, %struct.Module*, i8* }
|
%struct.NamedMDNode = type { %struct.ilist_node.6, %struct.basic_string, ptr, ptr }
|
||||||
%struct.ValueSymbolTable = type opaque
|
%struct.ValueSymbolTable = type opaque
|
||||||
%struct.OwningPtr = type { %struct.GVMaterializer* }
|
%struct.OwningPtr = type { ptr }
|
||||||
%struct.GVMaterializer = type opaque
|
%struct.GVMaterializer = type opaque
|
||||||
%struct.iplist.4 = type { %struct.ilist_traits.3, %struct.BasicBlock* }
|
%struct.iplist.4 = type { %struct.ilist_traits.3, ptr }
|
||||||
%struct.ilist_traits.3 = type { %struct.ilist_half_node.23 }
|
%struct.ilist_traits.3 = type { %struct.ilist_half_node.23 }
|
||||||
%struct.iplist = type { %struct.ilist_traits, %struct.Argument* }
|
%struct.iplist = type { %struct.ilist_traits, ptr }
|
||||||
%struct.ilist_traits = type { %struct.ilist_half_node }
|
%struct.ilist_traits = type { %struct.ilist_half_node }
|
||||||
%struct.ilist_half_node = type { %struct.Argument* }
|
%struct.ilist_half_node = type { ptr }
|
||||||
%struct.Argument = type { %struct.Value, %struct.ilist_node, %struct.Function* }
|
%struct.Argument = type { %struct.Value, %struct.ilist_node, ptr }
|
||||||
%struct.ilist_node = type { %struct.ilist_half_node, %struct.Argument* }
|
%struct.ilist_node = type { %struct.ilist_half_node, ptr }
|
||||||
%struct.AttrListPtr = type { %struct.AttributeListImpl* }
|
%struct.AttrListPtr = type { ptr }
|
||||||
%struct.AttributeListImpl = type opaque
|
%struct.AttributeListImpl = type opaque
|
||||||
|
|
||||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
|
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind
|
||||||
|
|
||||||
; CHECK: _ZSt9iter_swapIPSt4pairIPN4llvm10BasicBlockEjES5_EvT_T0_
|
; CHECK: _ZSt9iter_swapIPSt4pairIPN4llvm10BasicBlockEjES5_EvT_T0_
|
||||||
; CHECK: store
|
; CHECK: store
|
||||||
; CHECK: ret void
|
; CHECK: ret void
|
||||||
define void @_ZSt9iter_swapIPSt4pairIPN4llvm10BasicBlockEjES5_EvT_T0_(%struct.pair.162* %__a, %struct.pair.162* %__b) nounwind uwtable inlinehint {
|
define void @_ZSt9iter_swapIPSt4pairIPN4llvm10BasicBlockEjES5_EvT_T0_(ptr %__a, ptr %__b) nounwind uwtable inlinehint {
|
||||||
entry:
|
entry:
|
||||||
%memtmp = alloca %struct.pair.162, align 8
|
%memtmp = alloca %struct.pair.162, align 8
|
||||||
%0 = getelementptr inbounds %struct.pair.162, %struct.pair.162* %memtmp, i64 0, i32 0
|
%0 = load ptr, ptr %__a, align 8
|
||||||
%1 = getelementptr inbounds %struct.pair.162, %struct.pair.162* %__a, i64 0, i32 0
|
store ptr %0, ptr %memtmp, align 8
|
||||||
%2 = load %struct.BasicBlock*, %struct.BasicBlock** %1, align 8
|
%1 = getelementptr inbounds %struct.pair.162, ptr %memtmp, i64 0, i32 1
|
||||||
store %struct.BasicBlock* %2, %struct.BasicBlock** %0, align 8
|
%2 = getelementptr inbounds %struct.pair.162, ptr %__a, i64 0, i32 1
|
||||||
%3 = getelementptr inbounds %struct.pair.162, %struct.pair.162* %memtmp, i64 0, i32 1
|
%3 = load i32, ptr %2, align 4
|
||||||
%4 = getelementptr inbounds %struct.pair.162, %struct.pair.162* %__a, i64 0, i32 1
|
store i32 %3, ptr %1, align 8
|
||||||
%5 = load i32, i32* %4, align 4
|
call void @llvm.memcpy.p0.p0.i64(ptr %__a, ptr %__b, i64 12, i1 false)
|
||||||
store i32 %5, i32* %3, align 8
|
call void @llvm.memcpy.p0.p0.i64(ptr %__b, ptr %memtmp, i64 12, i1 false)
|
||||||
%6 = bitcast %struct.pair.162* %__a to i8*
|
|
||||||
%7 = bitcast %struct.pair.162* %__b to i8*
|
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %6, i8* %7, i64 12, i1 false)
|
|
||||||
%8 = bitcast %struct.pair.162* %memtmp to i8*
|
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %7, i8* %8, i64 12, i1 false)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,28 +5,27 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define void @_UPT_destroy(i8* nocapture %ptr) local_unnamed_addr #0 {
|
define void @_UPT_destroy(ptr nocapture %ptr) local_unnamed_addr #0 {
|
||||||
entry:
|
entry:
|
||||||
%edi = getelementptr inbounds i8, i8* %ptr, i64 8
|
%edi = getelementptr inbounds i8, ptr %ptr, i64 8
|
||||||
|
|
||||||
; CHECK-NOT: tail call void @llvm.memset.p0i8.i64(i8* align 8 %edi, i8 0, i64 176, i1 false)
|
; CHECK-NOT: tail call void @llvm.memset.p0.i64(ptr align 8 %edi, i8 0, i64 176, i1 false)
|
||||||
; CHECK-NOT: store i32 -1, i32* %addr
|
; CHECK-NOT: store i32 -1, ptr %addr
|
||||||
|
|
||||||
tail call void @llvm.memset.p0i8.i64(i8* align 8 %edi, i8 0, i64 176, i1 false)
|
tail call void @llvm.memset.p0.i64(ptr align 8 %edi, i8 0, i64 176, i1 false)
|
||||||
%format4.i = getelementptr inbounds i8, i8* %ptr, i64 144
|
%format4.i = getelementptr inbounds i8, ptr %ptr, i64 144
|
||||||
%addr = bitcast i8* %format4.i to i32*
|
store i32 -1, ptr %format4.i, align 8
|
||||||
store i32 -1, i32* %addr, align 8
|
|
||||||
|
|
||||||
; CHECK: tail call void @free
|
; CHECK: tail call void @free
|
||||||
tail call void @free(i8* nonnull %ptr)
|
tail call void @free(ptr nonnull %ptr)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
declare void @free(i8* nocapture allocptr) local_unnamed_addr #0
|
declare void @free(ptr nocapture allocptr) local_unnamed_addr #0
|
||||||
|
|
||||||
; Function Attrs: argmemonly nounwind
|
; Function Attrs: argmemonly nounwind
|
||||||
declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1) #1
|
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1) #1
|
||||||
|
|
||||||
attributes #0 = { nounwind allockind("free")}
|
attributes #0 = { nounwind allockind("free")}
|
||||||
attributes #1 = { argmemonly nounwind }
|
attributes #1 = { argmemonly nounwind }
|
||||||
|
|
|
@ -1,489 +1,404 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||||
; RUN: opt < %s -basic-aa -dse -S | FileCheck %s
|
; RUN: opt < %s -basic-aa -dse -S | FileCheck %s
|
||||||
|
|
||||||
define void @write4to7(i32* nocapture %p) {
|
define void @write4to7(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @write4to7(
|
; CHECK-LABEL: @write4to7(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARRAYIDX0]], i64 4
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP0]], i8 0, i64 24, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false)
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 1
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
|
; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX1]], align 4
|
||||||
; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX1]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
|
%arrayidx0 = getelementptr inbounds i32, ptr %p, i64 1
|
||||||
%p3 = bitcast i32* %arrayidx0 to i8*
|
call void @llvm.memset.p0.i64(ptr align 4 %arrayidx0, i8 0, i64 28, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i1 false)
|
%arrayidx1 = getelementptr inbounds i32, ptr %p, i64 1
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32* %p, i64 1
|
store i32 1, ptr %arrayidx1, align 4
|
||||||
store i32 1, i32* %arrayidx1, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write4to7_weird_element_type(i32* nocapture %p) {
|
define void @write4to7_weird_element_type(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @write4to7_weird_element_type(
|
; CHECK-LABEL: @write4to7_weird_element_type(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
|
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[ARRAYIDX0]], i64 4
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[TMP0]], i64 4
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP1]], i8 0, i64 24, i1 false)
|
||||||
; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 1
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i32.i64(i32* align 4 [[TMP2]], i8 0, i64 24, i1 false)
|
; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX1]], align 4
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
|
|
||||||
; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX1]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
|
%arrayidx0 = getelementptr inbounds i32, ptr %p, i64 1
|
||||||
call void @llvm.memset.p0i32.i64(i32* align 4 %arrayidx0, i8 0, i64 28, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 4 %arrayidx0, i8 0, i64 28, i1 false)
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32* %p, i64 1
|
%arrayidx1 = getelementptr inbounds i32, ptr %p, i64 1
|
||||||
store i32 1, i32* %arrayidx1, align 4
|
store i32 1, ptr %arrayidx1, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write4to7_addrspace(i32 addrspace(1)* nocapture %p) {
|
define void @write4to7_addrspace(ptr addrspace(1) nocapture %p) {
|
||||||
; CHECK-LABEL: @write4to7_addrspace(
|
; CHECK-LABEL: @write4to7_addrspace(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32 addrspace(1)* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr addrspace(1) [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32 addrspace(1)* [[ARRAYIDX0]] to i8 addrspace(1)*
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[ARRAYIDX0]], i64 4
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[P3]], i64 4
|
; CHECK-NEXT: call void @llvm.memset.p1.i64(ptr addrspace(1) align 4 [[TMP0]], i8 0, i64 24, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p1i8.i64(i8 addrspace(1)* align 4 [[TMP0]], i8 0, i64 24, i1 false)
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr addrspace(1) [[P]], i64 1
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32 addrspace(1)* [[P]], i64 1
|
; CHECK-NEXT: store i32 1, ptr addrspace(1) [[ARRAYIDX1]], align 4
|
||||||
; CHECK-NEXT: store i32 1, i32 addrspace(1)* [[ARRAYIDX1]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32 addrspace(1)* %p, i64 1
|
%arrayidx0 = getelementptr inbounds i32, ptr addrspace(1) %p, i64 1
|
||||||
%p3 = bitcast i32 addrspace(1)* %arrayidx0 to i8 addrspace(1)*
|
call void @llvm.memset.p1.i64(ptr addrspace(1) align 4 %arrayidx0, i8 0, i64 28, i1 false)
|
||||||
call void @llvm.memset.p1i8.i64(i8 addrspace(1)* align 4 %p3, i8 0, i64 28, i1 false)
|
%arrayidx1 = getelementptr inbounds i32, ptr addrspace(1) %p, i64 1
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32 addrspace(1)* %p, i64 1
|
store i32 1, ptr addrspace(1) %arrayidx1, align 4
|
||||||
store i32 1, i32 addrspace(1)* %arrayidx1, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write4to7_atomic(i32* nocapture %p) {
|
define void @write4to7_atomic(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @write4to7_atomic(
|
; CHECK-LABEL: @write4to7_atomic(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARRAYIDX0]], i64 4
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
|
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 [[TMP0]], i8 0, i64 24, i32 4)
|
||||||
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i32 4)
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 1
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
|
; CHECK-NEXT: store atomic i32 1, ptr [[ARRAYIDX1]] unordered, align 4
|
||||||
; CHECK-NEXT: store atomic i32 1, i32* [[ARRAYIDX1]] unordered, align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
|
%arrayidx0 = getelementptr inbounds i32, ptr %p, i64 1
|
||||||
%p3 = bitcast i32* %arrayidx0 to i8*
|
call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 %arrayidx0, i8 0, i64 28, i32 4)
|
||||||
call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4)
|
%arrayidx1 = getelementptr inbounds i32, ptr %p, i64 1
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32* %p, i64 1
|
store atomic i32 1, ptr %arrayidx1 unordered, align 4
|
||||||
store atomic i32 1, i32* %arrayidx1 unordered, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write0to3(i32* nocapture %p) {
|
define void @write0to3(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @write0to3(
|
; CHECK-LABEL: @write0to3(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 4
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP0]], i8 0, i64 24, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false)
|
; CHECK-NEXT: store i32 1, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p3 = bitcast i32* %p to i8*
|
call void @llvm.memset.p0.i64(ptr align 4 %p, i8 0, i64 28, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i1 false)
|
store i32 1, ptr %p, align 4
|
||||||
store i32 1, i32* %p, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write0to3_atomic(i32* nocapture %p) {
|
define void @write0to3_atomic(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @write0to3_atomic(
|
; CHECK-LABEL: @write0to3_atomic(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 4
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
|
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 [[TMP0]], i8 0, i64 24, i32 4)
|
||||||
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i32 4)
|
; CHECK-NEXT: store atomic i32 1, ptr [[P]] unordered, align 4
|
||||||
; CHECK-NEXT: store atomic i32 1, i32* [[P]] unordered, align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p3 = bitcast i32* %p to i8*
|
call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 %p, i8 0, i64 28, i32 4)
|
||||||
call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4)
|
store atomic i32 1, ptr %p unordered, align 4
|
||||||
store atomic i32 1, i32* %p unordered, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Atomicity of the store is weaker from the memset
|
; Atomicity of the store is weaker from the memset
|
||||||
define void @write0to3_atomic_weaker(i32* nocapture %p) {
|
define void @write0to3_atomic_weaker(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @write0to3_atomic_weaker(
|
; CHECK-LABEL: @write0to3_atomic_weaker(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 4
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
|
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 [[TMP0]], i8 0, i64 24, i32 4)
|
||||||
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i32 4)
|
; CHECK-NEXT: store i32 1, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p3 = bitcast i32* %p to i8*
|
call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 %p, i8 0, i64 28, i32 4)
|
||||||
call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4)
|
store i32 1, ptr %p, align 4
|
||||||
store i32 1, i32* %p, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write0to7(i32* nocapture %p) {
|
define void @write0to7(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @write0to7(
|
; CHECK-LABEL: @write0to7(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 8
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 8
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP0]], i8 0, i64 24, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false)
|
; CHECK-NEXT: store i64 1, ptr [[P]], align 8
|
||||||
; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i64*
|
|
||||||
; CHECK-NEXT: store i64 1, i64* [[P4]], align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p3 = bitcast i32* %p to i8*
|
call void @llvm.memset.p0.i64(ptr align 4 %p, i8 0, i64 32, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i1 false)
|
store i64 1, ptr %p, align 8
|
||||||
%p4 = bitcast i32* %p to i64*
|
|
||||||
store i64 1, i64* %p4, align 8
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Changing the memset start and length is okay here because the
|
; Changing the memset start and length is okay here because the
|
||||||
; store is a multiple of the memset element size
|
; store is a multiple of the memset element size
|
||||||
define void @write0to7_atomic(i32* nocapture %p) {
|
define void @write0to7_atomic(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @write0to7_atomic(
|
; CHECK-LABEL: @write0to7_atomic(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 8
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 8
|
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 [[TMP0]], i8 0, i64 24, i32 4)
|
||||||
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i32 4)
|
; CHECK-NEXT: store atomic i64 1, ptr [[P]] unordered, align 8
|
||||||
; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i64*
|
|
||||||
; CHECK-NEXT: store atomic i64 1, i64* [[P4]] unordered, align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p3 = bitcast i32* %p to i8*
|
call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 %p, i8 0, i64 32, i32 4)
|
||||||
call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i32 4)
|
store atomic i64 1, ptr %p unordered, align 8
|
||||||
%p4 = bitcast i32* %p to i64*
|
|
||||||
store atomic i64 1, i64* %p4 unordered, align 8
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write0to7_2(i32* nocapture %p) {
|
define void @write0to7_2(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @write0to7_2(
|
; CHECK-LABEL: @write0to7_2(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARRAYIDX0]], i64 4
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP0]], i8 0, i64 24, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false)
|
; CHECK-NEXT: store i64 1, ptr [[P]], align 8
|
||||||
; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i64*
|
|
||||||
; CHECK-NEXT: store i64 1, i64* [[P4]], align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
|
%arrayidx0 = getelementptr inbounds i32, ptr %p, i64 1
|
||||||
%p3 = bitcast i32* %arrayidx0 to i8*
|
call void @llvm.memset.p0.i64(ptr align 4 %arrayidx0, i8 0, i64 28, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i1 false)
|
store i64 1, ptr %p, align 8
|
||||||
%p4 = bitcast i32* %p to i64*
|
|
||||||
store i64 1, i64* %p4, align 8
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write0to7_2_atomic(i32* nocapture %p) {
|
define void @write0to7_2_atomic(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @write0to7_2_atomic(
|
; CHECK-LABEL: @write0to7_2_atomic(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARRAYIDX0]], i64 4
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
|
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 [[TMP0]], i8 0, i64 24, i32 4)
|
||||||
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i32 4)
|
; CHECK-NEXT: store atomic i64 1, ptr [[P]] unordered, align 8
|
||||||
; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i64*
|
|
||||||
; CHECK-NEXT: store atomic i64 1, i64* [[P4]] unordered, align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
|
%arrayidx0 = getelementptr inbounds i32, ptr %p, i64 1
|
||||||
%p3 = bitcast i32* %arrayidx0 to i8*
|
call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 %arrayidx0, i8 0, i64 28, i32 4)
|
||||||
call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4)
|
store atomic i64 1, ptr %p unordered, align 8
|
||||||
%p4 = bitcast i32* %p to i64*
|
|
||||||
store atomic i64 1, i64* %p4 unordered, align 8
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; We do not trim the beginning of the eariler write if the alignment of the
|
; We do not trim the beginning of the eariler write if the alignment of the
|
||||||
; start pointer is changed.
|
; start pointer is changed.
|
||||||
define void @dontwrite0to3_align8(i32* nocapture %p) {
|
define void @dontwrite0to3_align8(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @dontwrite0to3_align8(
|
; CHECK-LABEL: @dontwrite0to3_align8(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[P:%.*]], i8 0, i64 32, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 8 [[P3]], i8 0, i64 32, i1 false)
|
; CHECK-NEXT: store i32 1, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p3 = bitcast i32* %p to i8*
|
call void @llvm.memset.p0.i64(ptr align 8 %p, i8 0, i64 32, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 8 %p3, i8 0, i64 32, i1 false)
|
store i32 1, ptr %p, align 4
|
||||||
store i32 1, i32* %p, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @dontwrite0to3_align8_atomic(i32* nocapture %p) {
|
define void @dontwrite0to3_align8_atomic(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @dontwrite0to3_align8_atomic(
|
; CHECK-LABEL: @dontwrite0to3_align8_atomic(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
|
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 8 [[P:%.*]], i8 0, i64 32, i32 4)
|
||||||
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[P3]], i8 0, i64 32, i32 4)
|
; CHECK-NEXT: store atomic i32 1, ptr [[P]] unordered, align 4
|
||||||
; CHECK-NEXT: store atomic i32 1, i32* [[P]] unordered, align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p3 = bitcast i32* %p to i8*
|
call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 8 %p, i8 0, i64 32, i32 4)
|
||||||
call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %p3, i8 0, i64 32, i32 4)
|
store atomic i32 1, ptr %p unordered, align 4
|
||||||
store atomic i32 1, i32* %p unordered, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @dontwrite0to1(i32* nocapture %p) {
|
define void @dontwrite0to1(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @dontwrite0to1(
|
; CHECK-LABEL: @dontwrite0to1(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[P:%.*]], i8 0, i64 32, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 32, i1 false)
|
; CHECK-NEXT: store i16 1, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i16*
|
|
||||||
; CHECK-NEXT: store i16 1, i16* [[P4]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p3 = bitcast i32* %p to i8*
|
call void @llvm.memset.p0.i64(ptr align 4 %p, i8 0, i64 32, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i1 false)
|
store i16 1, ptr %p, align 4
|
||||||
%p4 = bitcast i32* %p to i16*
|
|
||||||
store i16 1, i16* %p4, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @dontwrite0to1_atomic(i32* nocapture %p) {
|
define void @dontwrite0to1_atomic(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @dontwrite0to1_atomic(
|
; CHECK-LABEL: @dontwrite0to1_atomic(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
|
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 [[P:%.*]], i8 0, i64 32, i32 4)
|
||||||
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 32, i32 4)
|
; CHECK-NEXT: store atomic i16 1, ptr [[P]] unordered, align 4
|
||||||
; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i16*
|
|
||||||
; CHECK-NEXT: store atomic i16 1, i16* [[P4]] unordered, align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p3 = bitcast i32* %p to i8*
|
call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 %p, i8 0, i64 32, i32 4)
|
||||||
call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i32 4)
|
store atomic i16 1, ptr %p unordered, align 4
|
||||||
%p4 = bitcast i32* %p to i16*
|
|
||||||
store atomic i16 1, i16* %p4 unordered, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write2to10(i32* nocapture %p) {
|
define void @write2to10(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @write2to10(
|
; CHECK-LABEL: @write2to10(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARRAYIDX0]], i64 4
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP0]], i8 0, i64 28, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 28, i1 false)
|
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i16, ptr [[P]], i64 1
|
||||||
; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i16*
|
; CHECK-NEXT: store i64 1, ptr [[ARRAYIDX2]], align 8
|
||||||
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i16, i16* [[P4]], i64 1
|
|
||||||
; CHECK-NEXT: [[P5:%.*]] = bitcast i16* [[ARRAYIDX2]] to i64*
|
|
||||||
; CHECK-NEXT: store i64 1, i64* [[P5]], align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
|
%arrayidx0 = getelementptr inbounds i32, ptr %p, i64 1
|
||||||
%p3 = bitcast i32* %arrayidx0 to i8*
|
call void @llvm.memset.p0.i64(ptr align 4 %arrayidx0, i8 0, i64 32, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i1 false)
|
%arrayidx2 = getelementptr inbounds i16, ptr %p, i64 1
|
||||||
%p4 = bitcast i32* %p to i16*
|
store i64 1, ptr %arrayidx2, align 8
|
||||||
%arrayidx2 = getelementptr inbounds i16, i16* %p4, i64 1
|
|
||||||
%p5 = bitcast i16* %arrayidx2 to i64*
|
|
||||||
store i64 1, i64* %p5, align 8
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write2to10_atomic(i32* nocapture %p) {
|
define void @write2to10_atomic(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @write2to10_atomic(
|
; CHECK-LABEL: @write2to10_atomic(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARRAYIDX0]], i64 4
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
|
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 [[TMP0]], i8 0, i64 28, i32 4)
|
||||||
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 28, i32 4)
|
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i16, ptr [[P]], i64 1
|
||||||
; CHECK-NEXT: [[P4:%.*]] = bitcast i32* [[P]] to i16*
|
; CHECK-NEXT: store atomic i64 1, ptr [[ARRAYIDX2]] unordered, align 8
|
||||||
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i16, i16* [[P4]], i64 1
|
|
||||||
; CHECK-NEXT: [[P5:%.*]] = bitcast i16* [[ARRAYIDX2]] to i64*
|
|
||||||
; CHECK-NEXT: store atomic i64 1, i64* [[P5]] unordered, align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
|
%arrayidx0 = getelementptr inbounds i32, ptr %p, i64 1
|
||||||
%p3 = bitcast i32* %arrayidx0 to i8*
|
call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 %arrayidx0, i8 0, i64 32, i32 4)
|
||||||
call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i32 4)
|
%arrayidx2 = getelementptr inbounds i16, ptr %p, i64 1
|
||||||
%p4 = bitcast i32* %p to i16*
|
store atomic i64 1, ptr %arrayidx2 unordered, align 8
|
||||||
%arrayidx2 = getelementptr inbounds i16, i16* %p4, i64 1
|
|
||||||
%p5 = bitcast i16* %arrayidx2 to i64*
|
|
||||||
store atomic i64 1, i64* %p5 unordered, align 8
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write8To15AndThen0To7(i64* nocapture %P) {
|
define void @write8To15AndThen0To7(ptr nocapture %P) {
|
||||||
; CHECK-LABEL: @write8To15AndThen0To7(
|
; CHECK-LABEL: @write8To15AndThen0To7(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8*
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 16
|
||||||
; CHECK-NEXT: [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0
|
; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr align 8 [[TMP0]], i8 0, i64 16, i1 false)
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[MYBASE0]], i64 16
|
; CHECK-NEXT: [[BASE64_1:%.*]] = getelementptr inbounds i64, ptr [[P]], i64 1
|
||||||
; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* align 8 [[TMP0]], i8 0, i64 16, i1 false)
|
; CHECK-NEXT: store i64 1, ptr [[BASE64_1]], align 4
|
||||||
; CHECK-NEXT: [[BASE64_0:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 0
|
; CHECK-NEXT: store i64 2, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: [[BASE64_1:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 1
|
|
||||||
; CHECK-NEXT: store i64 1, i64* [[BASE64_1]], align 4
|
|
||||||
; CHECK-NEXT: store i64 2, i64* [[BASE64_0]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
%base0 = bitcast i64* %P to i8*
|
tail call void @llvm.memset.p0.i64(ptr align 8 %P, i8 0, i64 32, i1 false)
|
||||||
%mybase0 = getelementptr inbounds i8, i8* %base0, i64 0
|
|
||||||
tail call void @llvm.memset.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i1 false)
|
|
||||||
|
|
||||||
%base64_0 = getelementptr inbounds i64, i64* %P, i64 0
|
%base64_1 = getelementptr inbounds i64, ptr %P, i64 1
|
||||||
%base64_1 = getelementptr inbounds i64, i64* %P, i64 1
|
|
||||||
|
|
||||||
store i64 1, i64* %base64_1
|
store i64 1, ptr %base64_1
|
||||||
store i64 2, i64* %base64_0
|
store i64 2, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write8To15AndThen0To7_atomic(i64* nocapture %P) {
|
define void @write8To15AndThen0To7_atomic(ptr nocapture %P) {
|
||||||
; CHECK-LABEL: @write8To15AndThen0To7_atomic(
|
; CHECK-LABEL: @write8To15AndThen0To7_atomic(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8*
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 16
|
||||||
; CHECK-NEXT: [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0
|
; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 8 [[TMP0]], i8 0, i64 16, i32 8)
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[MYBASE0]], i64 16
|
; CHECK-NEXT: [[BASE64_1:%.*]] = getelementptr inbounds i64, ptr [[P]], i64 1
|
||||||
; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[TMP0]], i8 0, i64 16, i32 8)
|
; CHECK-NEXT: store atomic i64 1, ptr [[BASE64_1]] unordered, align 8
|
||||||
; CHECK-NEXT: [[BASE64_0:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 0
|
; CHECK-NEXT: store atomic i64 2, ptr [[P]] unordered, align 8
|
||||||
; CHECK-NEXT: [[BASE64_1:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 1
|
|
||||||
; CHECK-NEXT: store atomic i64 1, i64* [[BASE64_1]] unordered, align 8
|
|
||||||
; CHECK-NEXT: store atomic i64 2, i64* [[BASE64_0]] unordered, align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
%base0 = bitcast i64* %P to i8*
|
tail call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 8 %P, i8 0, i64 32, i32 8)
|
||||||
%mybase0 = getelementptr inbounds i8, i8* %base0, i64 0
|
|
||||||
tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i32 8)
|
|
||||||
|
|
||||||
%base64_0 = getelementptr inbounds i64, i64* %P, i64 0
|
%base64_1 = getelementptr inbounds i64, ptr %P, i64 1
|
||||||
%base64_1 = getelementptr inbounds i64, i64* %P, i64 1
|
|
||||||
|
|
||||||
store atomic i64 1, i64* %base64_1 unordered, align 8
|
store atomic i64 1, ptr %base64_1 unordered, align 8
|
||||||
store atomic i64 2, i64* %base64_0 unordered, align 8
|
store atomic i64 2, ptr %P unordered, align 8
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write8To15AndThen0To7_atomic_weaker(i64* nocapture %P) {
|
define void @write8To15AndThen0To7_atomic_weaker(ptr nocapture %P) {
|
||||||
; CHECK-LABEL: @write8To15AndThen0To7_atomic_weaker(
|
; CHECK-LABEL: @write8To15AndThen0To7_atomic_weaker(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8*
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 16
|
||||||
; CHECK-NEXT: [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0
|
; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 8 [[TMP0]], i8 0, i64 16, i32 8)
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[MYBASE0]], i64 16
|
; CHECK-NEXT: [[BASE64_1:%.*]] = getelementptr inbounds i64, ptr [[P]], i64 1
|
||||||
; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[TMP0]], i8 0, i64 16, i32 8)
|
; CHECK-NEXT: store atomic i64 1, ptr [[BASE64_1]] unordered, align 8
|
||||||
; CHECK-NEXT: [[BASE64_0:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 0
|
; CHECK-NEXT: store i64 2, ptr [[P]], align 8
|
||||||
; CHECK-NEXT: [[BASE64_1:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 1
|
|
||||||
; CHECK-NEXT: store atomic i64 1, i64* [[BASE64_1]] unordered, align 8
|
|
||||||
; CHECK-NEXT: store i64 2, i64* [[BASE64_0]], align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
%base0 = bitcast i64* %P to i8*
|
tail call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 8 %P, i8 0, i64 32, i32 8)
|
||||||
%mybase0 = getelementptr inbounds i8, i8* %base0, i64 0
|
|
||||||
tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i32 8)
|
|
||||||
|
|
||||||
%base64_0 = getelementptr inbounds i64, i64* %P, i64 0
|
%base64_1 = getelementptr inbounds i64, ptr %P, i64 1
|
||||||
%base64_1 = getelementptr inbounds i64, i64* %P, i64 1
|
|
||||||
|
|
||||||
store atomic i64 1, i64* %base64_1 unordered, align 8
|
store atomic i64 1, ptr %base64_1 unordered, align 8
|
||||||
store i64 2, i64* %base64_0, align 8
|
store i64 2, ptr %P, align 8
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write8To15AndThen0To7_atomic_weaker_2(i64* nocapture %P) {
|
define void @write8To15AndThen0To7_atomic_weaker_2(ptr nocapture %P) {
|
||||||
; CHECK-LABEL: @write8To15AndThen0To7_atomic_weaker_2(
|
; CHECK-LABEL: @write8To15AndThen0To7_atomic_weaker_2(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8*
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 16
|
||||||
; CHECK-NEXT: [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0
|
; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 8 [[TMP0]], i8 0, i64 16, i32 8)
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[MYBASE0]], i64 16
|
; CHECK-NEXT: [[BASE64_1:%.*]] = getelementptr inbounds i64, ptr [[P]], i64 1
|
||||||
; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[TMP0]], i8 0, i64 16, i32 8)
|
; CHECK-NEXT: store i64 1, ptr [[BASE64_1]], align 8
|
||||||
; CHECK-NEXT: [[BASE64_0:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 0
|
; CHECK-NEXT: store atomic i64 2, ptr [[P]] unordered, align 8
|
||||||
; CHECK-NEXT: [[BASE64_1:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 1
|
|
||||||
; CHECK-NEXT: store i64 1, i64* [[BASE64_1]], align 8
|
|
||||||
; CHECK-NEXT: store atomic i64 2, i64* [[BASE64_0]] unordered, align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
%base0 = bitcast i64* %P to i8*
|
tail call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 8 %P, i8 0, i64 32, i32 8)
|
||||||
%mybase0 = getelementptr inbounds i8, i8* %base0, i64 0
|
|
||||||
tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i32 8)
|
|
||||||
|
|
||||||
%base64_0 = getelementptr inbounds i64, i64* %P, i64 0
|
%base64_1 = getelementptr inbounds i64, ptr %P, i64 1
|
||||||
%base64_1 = getelementptr inbounds i64, i64* %P, i64 1
|
|
||||||
|
|
||||||
store i64 1, i64* %base64_1, align 8
|
store i64 1, ptr %base64_1, align 8
|
||||||
store atomic i64 2, i64* %base64_0 unordered, align 8
|
store atomic i64 2, ptr %P unordered, align 8
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
|
declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1) nounwind
|
||||||
declare void @llvm.memset.p0i32.i64(i32* nocapture, i8, i64, i1) nounwind
|
declare void @llvm.memset.p1.i64(ptr addrspace(1) nocapture, i8, i64, i1) nounwind
|
||||||
declare void @llvm.memset.p1i8.i64(i8 addrspace(1)* nocapture, i8, i64, i1) nounwind
|
declare void @llvm.memset.element.unordered.atomic.p0.i64(ptr nocapture, i8, i64, i32) nounwind
|
||||||
declare void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* nocapture, i8, i64, i32) nounwind
|
|
||||||
|
|
||||||
define void @ow_begin_align1(i8* nocapture %p) {
|
define void @ow_begin_align1(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @ow_begin_align1(
|
; CHECK-LABEL: @ow_begin_align1(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, i8* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P1]], i64 7
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 7
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP0]], i8 0, i64 25, i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP0]], i8 0, i64 25, i1 false)
|
||||||
; CHECK-NEXT: [[P2:%.*]] = bitcast i8* [[P]] to i64*
|
; CHECK-NEXT: store i64 1, ptr [[P]], align 1
|
||||||
; CHECK-NEXT: store i64 1, i64* [[P2]], align 1
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p1 = getelementptr inbounds i8, i8* %p, i64 1
|
%p1 = getelementptr inbounds i8, ptr %p, i64 1
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %p1, i8 0, i64 32, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %p1, i8 0, i64 32, i1 false)
|
||||||
%p2 = bitcast i8* %p to i64*
|
store i64 1, ptr %p, align 1
|
||||||
store i64 1, i64* %p2, align 1
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @ow_end_align4(i8* nocapture %p) {
|
define void @ow_end_align4(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @ow_end_align4(
|
; CHECK-LABEL: @ow_end_align4(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, i8* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P1]], i64 4
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 4
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 28, i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP0]], i8 0, i64 28, i1 false)
|
||||||
; CHECK-NEXT: [[P2:%.*]] = bitcast i8* [[P]] to i64*
|
; CHECK-NEXT: store i64 1, ptr [[P]], align 1
|
||||||
; CHECK-NEXT: store i64 1, i64* [[P2]], align 1
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p1 = getelementptr inbounds i8, i8* %p, i64 1
|
%p1 = getelementptr inbounds i8, ptr %p, i64 1
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 4 %p1, i8 0, i64 32, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 4 %p1, i8 0, i64 32, i1 false)
|
||||||
%p2 = bitcast i8* %p to i64*
|
store i64 1, ptr %p, align 1
|
||||||
store i64 1, i64* %p2, align 1
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @ow_end_align8(i8* nocapture %p) {
|
define void @ow_end_align8(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @ow_end_align8(
|
; CHECK-LABEL: @ow_end_align8(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, i8* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 8 [[P1]], i8 0, i64 32, i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[P1]], i8 0, i64 32, i1 false)
|
||||||
; CHECK-NEXT: [[P2:%.*]] = bitcast i8* [[P]] to i64*
|
; CHECK-NEXT: store i64 1, ptr [[P]], align 1
|
||||||
; CHECK-NEXT: store i64 1, i64* [[P2]], align 1
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p1 = getelementptr inbounds i8, i8* %p, i64 1
|
%p1 = getelementptr inbounds i8, ptr %p, i64 1
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 8 %p1, i8 0, i64 32, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 8 %p1, i8 0, i64 32, i1 false)
|
||||||
%p2 = bitcast i8* %p to i64*
|
store i64 1, ptr %p, align 1
|
||||||
store i64 1, i64* %p2, align 1
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,441 +8,387 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
|
||||||
@glob1 = global %struct.vec2 zeroinitializer, align 16
|
@glob1 = global %struct.vec2 zeroinitializer, align 16
|
||||||
@glob2 = global %struct.vec2plusi zeroinitializer, align 16
|
@glob2 = global %struct.vec2plusi zeroinitializer, align 16
|
||||||
|
|
||||||
define void @write24to28(i32* nocapture %p) nounwind uwtable ssp {
|
define void @write24to28(ptr nocapture %p) nounwind uwtable ssp {
|
||||||
; CHECK-LABEL: @write24to28(
|
; CHECK-LABEL: @write24to28(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ARRAYIDX0]], i8 0, i64 24, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 24, i1 false)
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 7
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 7
|
; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX1]], align 4
|
||||||
; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX1]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
|
%arrayidx0 = getelementptr inbounds i32, ptr %p, i64 1
|
||||||
%p3 = bitcast i32* %arrayidx0 to i8*
|
call void @llvm.memset.p0.i64(ptr align 4 %arrayidx0, i8 0, i64 28, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i1 false)
|
%arrayidx1 = getelementptr inbounds i32, ptr %p, i64 7
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32* %p, i64 7
|
store i32 1, ptr %arrayidx1, align 4
|
||||||
store i32 1, i32* %arrayidx1, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write24to28_atomic(i32* nocapture %p) nounwind uwtable ssp {
|
define void @write24to28_atomic(ptr nocapture %p) nounwind uwtable ssp {
|
||||||
; CHECK-LABEL: @write24to28_atomic(
|
; CHECK-LABEL: @write24to28_atomic(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
|
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 [[ARRAYIDX0]], i8 0, i64 24, i32 4)
|
||||||
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 24, i32 4)
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 7
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 7
|
; CHECK-NEXT: store atomic i32 1, ptr [[ARRAYIDX1]] unordered, align 4
|
||||||
; CHECK-NEXT: store atomic i32 1, i32* [[ARRAYIDX1]] unordered, align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
|
%arrayidx0 = getelementptr inbounds i32, ptr %p, i64 1
|
||||||
%p3 = bitcast i32* %arrayidx0 to i8*
|
call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 %arrayidx0, i8 0, i64 28, i32 4)
|
||||||
call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4)
|
%arrayidx1 = getelementptr inbounds i32, ptr %p, i64 7
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32* %p, i64 7
|
store atomic i32 1, ptr %arrayidx1 unordered, align 4
|
||||||
store atomic i32 1, i32* %arrayidx1 unordered, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Atomicity of the store is weaker from the memset
|
; Atomicity of the store is weaker from the memset
|
||||||
define void @write24to28_atomic_weaker(i32* nocapture %p) nounwind uwtable ssp {
|
define void @write24to28_atomic_weaker(ptr nocapture %p) nounwind uwtable ssp {
|
||||||
; CHECK-LABEL: @write24to28_atomic_weaker(
|
; CHECK-LABEL: @write24to28_atomic_weaker(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
|
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 [[ARRAYIDX0]], i8 0, i64 24, i32 4)
|
||||||
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 24, i32 4)
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 7
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 7
|
; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX1]], align 4
|
||||||
; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX1]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32* %p, i64 1
|
%arrayidx0 = getelementptr inbounds i32, ptr %p, i64 1
|
||||||
%p3 = bitcast i32* %arrayidx0 to i8*
|
call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 %arrayidx0, i8 0, i64 28, i32 4)
|
||||||
call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 28, i32 4)
|
%arrayidx1 = getelementptr inbounds i32, ptr %p, i64 7
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32* %p, i64 7
|
store i32 1, ptr %arrayidx1, align 4
|
||||||
store i32 1, i32* %arrayidx1, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write28to32(i32* nocapture %p) nounwind uwtable ssp {
|
define void @write28to32(ptr nocapture %p) nounwind uwtable ssp {
|
||||||
; CHECK-LABEL: @write28to32(
|
; CHECK-LABEL: @write28to32(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[P:%.*]], i8 0, i64 28, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i1 false)
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 7
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 7
|
; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX1]], align 4
|
||||||
; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX1]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p3 = bitcast i32* %p to i8*
|
call void @llvm.memset.p0.i64(ptr align 4 %p, i8 0, i64 32, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i1 false)
|
%arrayidx1 = getelementptr inbounds i32, ptr %p, i64 7
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32* %p, i64 7
|
store i32 1, ptr %arrayidx1, align 4
|
||||||
store i32 1, i32* %arrayidx1, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write28to32_atomic(i32* nocapture %p) nounwind uwtable ssp {
|
define void @write28to32_atomic(ptr nocapture %p) nounwind uwtable ssp {
|
||||||
; CHECK-LABEL: @write28to32_atomic(
|
; CHECK-LABEL: @write28to32_atomic(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
|
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 [[P:%.*]], i8 0, i64 28, i32 4)
|
||||||
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i32 4)
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 7
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 7
|
; CHECK-NEXT: store atomic i32 1, ptr [[ARRAYIDX1]] unordered, align 4
|
||||||
; CHECK-NEXT: store atomic i32 1, i32* [[ARRAYIDX1]] unordered, align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p3 = bitcast i32* %p to i8*
|
call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 4 %p, i8 0, i64 32, i32 4)
|
||||||
call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 4 %p3, i8 0, i64 32, i32 4)
|
%arrayidx1 = getelementptr inbounds i32, ptr %p, i64 7
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32* %p, i64 7
|
store atomic i32 1, ptr %arrayidx1 unordered, align 4
|
||||||
store atomic i32 1, i32* %arrayidx1 unordered, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @dontwrite28to32memset(i32* nocapture %p) nounwind uwtable ssp {
|
define void @dontwrite28to32memset(ptr nocapture %p) nounwind uwtable ssp {
|
||||||
; CHECK-LABEL: @dontwrite28to32memset(
|
; CHECK-LABEL: @dontwrite28to32memset(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[P:%.*]], i8 0, i64 32, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 16 [[P3]], i8 0, i64 32, i1 false)
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 7
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 7
|
; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX1]], align 4
|
||||||
; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX1]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p3 = bitcast i32* %p to i8*
|
call void @llvm.memset.p0.i64(ptr align 16 %p, i8 0, i64 32, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 16 %p3, i8 0, i64 32, i1 false)
|
%arrayidx1 = getelementptr inbounds i32, ptr %p, i64 7
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32* %p, i64 7
|
store i32 1, ptr %arrayidx1, align 4
|
||||||
store i32 1, i32* %arrayidx1, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @dontwrite28to32memset_atomic(i32* nocapture %p) nounwind uwtable ssp {
|
define void @dontwrite28to32memset_atomic(ptr nocapture %p) nounwind uwtable ssp {
|
||||||
; CHECK-LABEL: @dontwrite28to32memset_atomic(
|
; CHECK-LABEL: @dontwrite28to32memset_atomic(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
|
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 16 [[P:%.*]], i8 0, i64 32, i32 4)
|
||||||
; CHECK-NEXT: call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 16 [[P3]], i8 0, i64 32, i32 4)
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 7
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 7
|
; CHECK-NEXT: store atomic i32 1, ptr [[ARRAYIDX1]] unordered, align 4
|
||||||
; CHECK-NEXT: store atomic i32 1, i32* [[ARRAYIDX1]] unordered, align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p3 = bitcast i32* %p to i8*
|
call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 16 %p, i8 0, i64 32, i32 4)
|
||||||
call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 16 %p3, i8 0, i64 32, i32 4)
|
%arrayidx1 = getelementptr inbounds i32, ptr %p, i64 7
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32* %p, i64 7
|
store atomic i32 1, ptr %arrayidx1 unordered, align 4
|
||||||
store atomic i32 1, i32* %arrayidx1 unordered, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write32to36(%struct.vec2plusi* nocapture %p) nounwind uwtable ssp {
|
define void @write32to36(ptr nocapture %p) nounwind uwtable ssp {
|
||||||
; CHECK-LABEL: @write32to36(
|
; CHECK-LABEL: @write32to36(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = bitcast %struct.vec2plusi* [[P:%.*]] to i8*
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr align 16 [[P:%.*]], ptr align 16 @glob2, i64 32, i1 false)
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP0]], i8* align 16 bitcast (%struct.vec2plusi* @glob2 to i8*), i64 32, i1 false)
|
; CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_VEC2PLUSI:%.*]], ptr [[P]], i64 0, i32 2
|
||||||
; CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_VEC2PLUSI:%.*]], %struct.vec2plusi* [[P]], i64 0, i32 2
|
; CHECK-NEXT: store i32 1, ptr [[C]], align 4
|
||||||
; CHECK-NEXT: store i32 1, i32* [[C]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%0 = bitcast %struct.vec2plusi* %p to i8*
|
tail call void @llvm.memcpy.p0.p0.i64(ptr align 16 %p, ptr align 16 @glob2, i64 36, i1 false)
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %0, i8* align 16 bitcast (%struct.vec2plusi* @glob2 to i8*), i64 36, i1 false)
|
%c = getelementptr inbounds %struct.vec2plusi, ptr %p, i64 0, i32 2
|
||||||
%c = getelementptr inbounds %struct.vec2plusi, %struct.vec2plusi* %p, i64 0, i32 2
|
store i32 1, ptr %c, align 4
|
||||||
store i32 1, i32* %c, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write32to36_atomic(%struct.vec2plusi* nocapture %p) nounwind uwtable ssp {
|
define void @write32to36_atomic(ptr nocapture %p) nounwind uwtable ssp {
|
||||||
; CHECK-LABEL: @write32to36_atomic(
|
; CHECK-LABEL: @write32to36_atomic(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = bitcast %struct.vec2plusi* [[P:%.*]] to i8*
|
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 16 [[P:%.*]], ptr align 16 @glob2, i64 32, i32 4)
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 16 [[TMP0]], i8* align 16 bitcast (%struct.vec2plusi* @glob2 to i8*), i64 32, i32 4)
|
; CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_VEC2PLUSI:%.*]], ptr [[P]], i64 0, i32 2
|
||||||
; CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_VEC2PLUSI:%.*]], %struct.vec2plusi* [[P]], i64 0, i32 2
|
; CHECK-NEXT: store atomic i32 1, ptr [[C]] unordered, align 4
|
||||||
; CHECK-NEXT: store atomic i32 1, i32* [[C]] unordered, align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%0 = bitcast %struct.vec2plusi* %p to i8*
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 16 %p, ptr align 16 @glob2, i64 36, i32 4)
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 16 %0, i8* align 16 bitcast (%struct.vec2plusi* @glob2 to i8*), i64 36, i32 4)
|
%c = getelementptr inbounds %struct.vec2plusi, ptr %p, i64 0, i32 2
|
||||||
%c = getelementptr inbounds %struct.vec2plusi, %struct.vec2plusi* %p, i64 0, i32 2
|
store atomic i32 1, ptr %c unordered, align 4
|
||||||
store atomic i32 1, i32* %c unordered, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Atomicity of the store is weaker than the memcpy
|
; Atomicity of the store is weaker than the memcpy
|
||||||
define void @write32to36_atomic_weaker(%struct.vec2plusi* nocapture %p) nounwind uwtable ssp {
|
define void @write32to36_atomic_weaker(ptr nocapture %p) nounwind uwtable ssp {
|
||||||
; CHECK-LABEL: @write32to36_atomic_weaker(
|
; CHECK-LABEL: @write32to36_atomic_weaker(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = bitcast %struct.vec2plusi* [[P:%.*]] to i8*
|
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 16 [[P:%.*]], ptr align 16 @glob2, i64 32, i32 4)
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 16 [[TMP0]], i8* align 16 bitcast (%struct.vec2plusi* @glob2 to i8*), i64 32, i32 4)
|
; CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_VEC2PLUSI:%.*]], ptr [[P]], i64 0, i32 2
|
||||||
; CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_VEC2PLUSI:%.*]], %struct.vec2plusi* [[P]], i64 0, i32 2
|
; CHECK-NEXT: store i32 1, ptr [[C]], align 4
|
||||||
; CHECK-NEXT: store i32 1, i32* [[C]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%0 = bitcast %struct.vec2plusi* %p to i8*
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 16 %p, ptr align 16 @glob2, i64 36, i32 4)
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 16 %0, i8* align 16 bitcast (%struct.vec2plusi* @glob2 to i8*), i64 36, i32 4)
|
%c = getelementptr inbounds %struct.vec2plusi, ptr %p, i64 0, i32 2
|
||||||
%c = getelementptr inbounds %struct.vec2plusi, %struct.vec2plusi* %p, i64 0, i32 2
|
store i32 1, ptr %c, align 4
|
||||||
store i32 1, i32* %c, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write16to32(%struct.vec2* nocapture %p) nounwind uwtable ssp {
|
define void @write16to32(ptr nocapture %p) nounwind uwtable ssp {
|
||||||
; CHECK-LABEL: @write16to32(
|
; CHECK-LABEL: @write16to32(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = bitcast %struct.vec2* [[P:%.*]] to i8*
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr align 16 [[P:%.*]], ptr align 16 @glob1, i64 16, i1 false)
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP0]], i8* align 16 bitcast (%struct.vec2* @glob1 to i8*), i64 16, i1 false)
|
; CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_VEC2:%.*]], ptr [[P]], i64 0, i32 1
|
||||||
; CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_VEC2:%.*]], %struct.vec2* [[P]], i64 0, i32 1
|
; CHECK-NEXT: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr [[C]], align 4
|
||||||
; CHECK-NEXT: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, <4 x i32>* [[C]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%0 = bitcast %struct.vec2* %p to i8*
|
tail call void @llvm.memcpy.p0.p0.i64(ptr align 16 %p, ptr align 16 @glob1, i64 32, i1 false)
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %0, i8* align 16 bitcast (%struct.vec2* @glob1 to i8*), i64 32, i1 false)
|
%c = getelementptr inbounds %struct.vec2, ptr %p, i64 0, i32 1
|
||||||
%c = getelementptr inbounds %struct.vec2, %struct.vec2* %p, i64 0, i32 1
|
store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %c, align 4
|
||||||
store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, <4 x i32>* %c, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write16to32_atomic(%struct.vec2* nocapture %p) nounwind uwtable ssp {
|
define void @write16to32_atomic(ptr nocapture %p) nounwind uwtable ssp {
|
||||||
; CHECK-LABEL: @write16to32_atomic(
|
; CHECK-LABEL: @write16to32_atomic(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = bitcast %struct.vec2* [[P:%.*]] to i8*
|
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 16 [[P:%.*]], ptr align 16 @glob1, i64 16, i32 4)
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 16 [[TMP0]], i8* align 16 bitcast (%struct.vec2* @glob1 to i8*), i64 16, i32 4)
|
; CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_VEC2:%.*]], ptr [[P]], i64 0, i32 1
|
||||||
; CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_VEC2:%.*]], %struct.vec2* [[P]], i64 0, i32 1
|
; CHECK-NEXT: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr [[C]], align 4
|
||||||
; CHECK-NEXT: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, <4 x i32>* [[C]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%0 = bitcast %struct.vec2* %p to i8*
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 16 %p, ptr align 16 @glob1, i64 32, i32 4)
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 16 %0, i8* align 16 bitcast (%struct.vec2* @glob1 to i8*), i64 32, i32 4)
|
%c = getelementptr inbounds %struct.vec2, ptr %p, i64 0, i32 1
|
||||||
%c = getelementptr inbounds %struct.vec2, %struct.vec2* %p, i64 0, i32 1
|
store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %c, align 4
|
||||||
store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, <4 x i32>* %c, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @dontwrite28to32memcpy(%struct.vec2* nocapture %p) nounwind uwtable ssp {
|
define void @dontwrite28to32memcpy(ptr nocapture %p) nounwind uwtable ssp {
|
||||||
; CHECK-LABEL: @dontwrite28to32memcpy(
|
; CHECK-LABEL: @dontwrite28to32memcpy(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = bitcast %struct.vec2* [[P:%.*]] to i8*
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr align 16 [[P:%.*]], ptr align 16 @glob1, i64 32, i1 false)
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP0]], i8* align 16 bitcast (%struct.vec2* @glob1 to i8*), i64 32, i1 false)
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [[STRUCT_VEC2:%.*]], ptr [[P]], i64 0, i32 0, i64 7
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [[STRUCT_VEC2:%.*]], %struct.vec2* [[P]], i64 0, i32 0, i64 7
|
; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX1]], align 4
|
||||||
; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX1]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%0 = bitcast %struct.vec2* %p to i8*
|
tail call void @llvm.memcpy.p0.p0.i64(ptr align 16 %p, ptr align 16 @glob1, i64 32, i1 false)
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %0, i8* align 16 bitcast (%struct.vec2* @glob1 to i8*), i64 32, i1 false)
|
%arrayidx1 = getelementptr inbounds %struct.vec2, ptr %p, i64 0, i32 0, i64 7
|
||||||
%arrayidx1 = getelementptr inbounds %struct.vec2, %struct.vec2* %p, i64 0, i32 0, i64 7
|
store i32 1, ptr %arrayidx1, align 4
|
||||||
store i32 1, i32* %arrayidx1, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @dontwrite28to32memcpy_atomic(%struct.vec2* nocapture %p) nounwind uwtable ssp {
|
define void @dontwrite28to32memcpy_atomic(ptr nocapture %p) nounwind uwtable ssp {
|
||||||
; CHECK-LABEL: @dontwrite28to32memcpy_atomic(
|
; CHECK-LABEL: @dontwrite28to32memcpy_atomic(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = bitcast %struct.vec2* [[P:%.*]] to i8*
|
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 16 [[P:%.*]], ptr align 16 @glob1, i64 32, i32 4)
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 16 [[TMP0]], i8* align 16 bitcast (%struct.vec2* @glob1 to i8*), i64 32, i32 4)
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [[STRUCT_VEC2:%.*]], ptr [[P]], i64 0, i32 0, i64 7
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [[STRUCT_VEC2:%.*]], %struct.vec2* [[P]], i64 0, i32 0, i64 7
|
; CHECK-NEXT: store atomic i32 1, ptr [[ARRAYIDX1]] unordered, align 4
|
||||||
; CHECK-NEXT: store atomic i32 1, i32* [[ARRAYIDX1]] unordered, align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%0 = bitcast %struct.vec2* %p to i8*
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 16 %p, ptr align 16 @glob1, i64 32, i32 4)
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 16 %0, i8* align 16 bitcast (%struct.vec2* @glob1 to i8*), i64 32, i32 4)
|
%arrayidx1 = getelementptr inbounds %struct.vec2, ptr %p, i64 0, i32 0, i64 7
|
||||||
%arrayidx1 = getelementptr inbounds %struct.vec2, %struct.vec2* %p, i64 0, i32 0, i64 7
|
store atomic i32 1, ptr %arrayidx1 unordered, align 4
|
||||||
store atomic i32 1, i32* %arrayidx1 unordered, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
|
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind
|
||||||
declare void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind
|
declare void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i32) nounwind
|
||||||
declare void @llvm.memset.p0i8.i64(i8* 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
|
declare void @llvm.memset.element.unordered.atomic.p0.i64(ptr nocapture, i8, i64, i32) nounwind
|
||||||
|
|
||||||
%struct.trapframe = type { i64, i64, i64 }
|
%struct.trapframe = type { i64, i64, i64 }
|
||||||
|
|
||||||
; bugzilla 11455 - make sure negative GEP's don't break this optimisation
|
; bugzilla 11455 - make sure negative GEP's don't break this optimisation
|
||||||
define void @cpu_lwp_fork(%struct.trapframe* %md_regs, i64 %pcb_rsp0) nounwind uwtable noinline ssp {
|
define void @cpu_lwp_fork(ptr %md_regs, i64 %pcb_rsp0) nounwind uwtable noinline ssp {
|
||||||
; CHECK-LABEL: @cpu_lwp_fork(
|
; CHECK-LABEL: @cpu_lwp_fork(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = inttoptr i64 [[PCB_RSP0:%.*]] to %struct.trapframe*
|
; CHECK-NEXT: [[TMP0:%.*]] = inttoptr i64 [[PCB_RSP0:%.*]] to ptr
|
||||||
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_TRAPFRAME:%.*]], %struct.trapframe* [[TMP0]], i64 -1
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_TRAPFRAME:%.*]], ptr [[TMP0]], i64 -1
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = bitcast %struct.trapframe* [[ADD_PTR]] to i8*
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[ADD_PTR]], ptr [[MD_REGS:%.*]], i64 24, i1 false)
|
||||||
; CHECK-NEXT: [[TMP2:%.*]] = bitcast %struct.trapframe* [[MD_REGS:%.*]] to i8*
|
; CHECK-NEXT: [[TF_TRAPNO:%.*]] = getelementptr inbounds [[STRUCT_TRAPFRAME]], ptr [[TMP0]], i64 -1, i32 1
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[TMP1]], i8* [[TMP2]], i64 24, i1 false)
|
; CHECK-NEXT: store i64 3, ptr [[TF_TRAPNO]], align 8
|
||||||
; CHECK-NEXT: [[TF_TRAPNO:%.*]] = getelementptr inbounds [[STRUCT_TRAPFRAME]], %struct.trapframe* [[TMP0]], i64 -1, i32 1
|
|
||||||
; CHECK-NEXT: store i64 3, i64* [[TF_TRAPNO]], align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%0 = inttoptr i64 %pcb_rsp0 to %struct.trapframe*
|
%0 = inttoptr i64 %pcb_rsp0 to ptr
|
||||||
%add.ptr = getelementptr inbounds %struct.trapframe, %struct.trapframe* %0, i64 -1
|
%add.ptr = getelementptr inbounds %struct.trapframe, ptr %0, i64 -1
|
||||||
%1 = bitcast %struct.trapframe* %add.ptr to i8*
|
call void @llvm.memcpy.p0.p0.i64(ptr %add.ptr, ptr %md_regs, i64 24, i1 false)
|
||||||
%2 = bitcast %struct.trapframe* %md_regs to i8*
|
%tf_trapno = getelementptr inbounds %struct.trapframe, ptr %0, i64 -1, i32 1
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* %2, i64 24, i1 false)
|
store i64 3, ptr %tf_trapno, align 8
|
||||||
%tf_trapno = getelementptr inbounds %struct.trapframe, %struct.trapframe* %0, i64 -1, i32 1
|
|
||||||
store i64 3, i64* %tf_trapno, align 8
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write16To23AndThen24To31(i64* nocapture %P, i64 %n64, i32 %n32, i16 %n16, i8 %n8) {
|
define void @write16To23AndThen24To31(ptr nocapture %P, i64 %n64, i32 %n32, i16 %n16, i8 %n8) {
|
||||||
; CHECK-LABEL: @write16To23AndThen24To31(
|
; CHECK-LABEL: @write16To23AndThen24To31(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8*
|
; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr align 8 [[P:%.*]], i8 0, i64 16, i1 false)
|
||||||
; CHECK-NEXT: [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0
|
; CHECK-NEXT: [[BASE64_2:%.*]] = getelementptr inbounds i64, ptr [[P]], i64 2
|
||||||
; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* align 8 [[MYBASE0]], i8 0, i64 16, i1 false)
|
; CHECK-NEXT: [[BASE64_3:%.*]] = getelementptr inbounds i64, ptr [[P]], i64 3
|
||||||
; CHECK-NEXT: [[BASE64_2:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 2
|
; CHECK-NEXT: store i64 3, ptr [[BASE64_2]]
|
||||||
; CHECK-NEXT: [[BASE64_3:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 3
|
; CHECK-NEXT: store i64 3, ptr [[BASE64_3]]
|
||||||
; CHECK-NEXT: store i64 3, i64* [[BASE64_2]]
|
|
||||||
; CHECK-NEXT: store i64 3, i64* [[BASE64_3]]
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
%base0 = bitcast i64* %P to i8*
|
tail call void @llvm.memset.p0.i64(ptr align 8 %P, i8 0, i64 32, i1 false)
|
||||||
%mybase0 = getelementptr inbounds i8, i8* %base0, i64 0
|
|
||||||
tail call void @llvm.memset.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i1 false)
|
|
||||||
|
|
||||||
%base64_2 = getelementptr inbounds i64, i64* %P, i64 2
|
%base64_2 = getelementptr inbounds i64, ptr %P, i64 2
|
||||||
%base64_3 = getelementptr inbounds i64, i64* %P, i64 3
|
%base64_3 = getelementptr inbounds i64, ptr %P, i64 3
|
||||||
|
|
||||||
store i64 3, i64* %base64_2
|
store i64 3, ptr %base64_2
|
||||||
store i64 3, i64* %base64_3
|
store i64 3, ptr %base64_3
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write16To23AndThen24To31_atomic(i64* nocapture %P, i64 %n64, i32 %n32, i16 %n16, i8 %n8) {
|
define void @write16To23AndThen24To31_atomic(ptr nocapture %P, i64 %n64, i32 %n32, i16 %n16, i8 %n8) {
|
||||||
; CHECK-LABEL: @write16To23AndThen24To31_atomic(
|
; CHECK-LABEL: @write16To23AndThen24To31_atomic(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8*
|
; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 8 [[P:%.*]], i8 0, i64 16, i32 8)
|
||||||
; CHECK-NEXT: [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0
|
; CHECK-NEXT: [[BASE64_2:%.*]] = getelementptr inbounds i64, ptr [[P]], i64 2
|
||||||
; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[MYBASE0]], i8 0, i64 16, i32 8)
|
; CHECK-NEXT: [[BASE64_3:%.*]] = getelementptr inbounds i64, ptr [[P]], i64 3
|
||||||
; CHECK-NEXT: [[BASE64_2:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 2
|
; CHECK-NEXT: store atomic i64 3, ptr [[BASE64_2]] unordered, align 8
|
||||||
; CHECK-NEXT: [[BASE64_3:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 3
|
; CHECK-NEXT: store atomic i64 3, ptr [[BASE64_3]] unordered, align 8
|
||||||
; CHECK-NEXT: store atomic i64 3, i64* [[BASE64_2]] unordered, align 8
|
|
||||||
; CHECK-NEXT: store atomic i64 3, i64* [[BASE64_3]] unordered, align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
%base0 = bitcast i64* %P to i8*
|
tail call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 8 %P, i8 0, i64 32, i32 8)
|
||||||
%mybase0 = getelementptr inbounds i8, i8* %base0, i64 0
|
|
||||||
tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i32 8)
|
|
||||||
|
|
||||||
%base64_2 = getelementptr inbounds i64, i64* %P, i64 2
|
%base64_2 = getelementptr inbounds i64, ptr %P, i64 2
|
||||||
%base64_3 = getelementptr inbounds i64, i64* %P, i64 3
|
%base64_3 = getelementptr inbounds i64, ptr %P, i64 3
|
||||||
|
|
||||||
store atomic i64 3, i64* %base64_2 unordered, align 8
|
store atomic i64 3, ptr %base64_2 unordered, align 8
|
||||||
store atomic i64 3, i64* %base64_3 unordered, align 8
|
store atomic i64 3, ptr %base64_3 unordered, align 8
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write16To23AndThen24To31_atomic_weaker1(i64* nocapture %P, i64 %n64, i32 %n32, i16 %n16, i8 %n8) {
|
define void @write16To23AndThen24To31_atomic_weaker1(ptr nocapture %P, i64 %n64, i32 %n32, i16 %n16, i8 %n8) {
|
||||||
; CHECK-LABEL: @write16To23AndThen24To31_atomic_weaker1(
|
; CHECK-LABEL: @write16To23AndThen24To31_atomic_weaker1(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8*
|
; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 8 [[P:%.*]], i8 0, i64 16, i32 8)
|
||||||
; CHECK-NEXT: [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0
|
; CHECK-NEXT: [[BASE64_2:%.*]] = getelementptr inbounds i64, ptr [[P]], i64 2
|
||||||
; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[MYBASE0]], i8 0, i64 16, i32 8)
|
; CHECK-NEXT: [[BASE64_3:%.*]] = getelementptr inbounds i64, ptr [[P]], i64 3
|
||||||
; CHECK-NEXT: [[BASE64_2:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 2
|
; CHECK-NEXT: store i64 3, ptr [[BASE64_2]], align 8
|
||||||
; CHECK-NEXT: [[BASE64_3:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 3
|
; CHECK-NEXT: store atomic i64 3, ptr [[BASE64_3]] unordered, align 8
|
||||||
; CHECK-NEXT: store i64 3, i64* [[BASE64_2]], align 8
|
|
||||||
; CHECK-NEXT: store atomic i64 3, i64* [[BASE64_3]] unordered, align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
%base0 = bitcast i64* %P to i8*
|
tail call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 8 %P, i8 0, i64 32, i32 8)
|
||||||
%mybase0 = getelementptr inbounds i8, i8* %base0, i64 0
|
|
||||||
tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i32 8)
|
|
||||||
|
|
||||||
%base64_2 = getelementptr inbounds i64, i64* %P, i64 2
|
%base64_2 = getelementptr inbounds i64, ptr %P, i64 2
|
||||||
%base64_3 = getelementptr inbounds i64, i64* %P, i64 3
|
%base64_3 = getelementptr inbounds i64, ptr %P, i64 3
|
||||||
|
|
||||||
store i64 3, i64* %base64_2, align 8
|
store i64 3, ptr %base64_2, align 8
|
||||||
store atomic i64 3, i64* %base64_3 unordered, align 8
|
store atomic i64 3, ptr %base64_3 unordered, align 8
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @write16To23AndThen24To31_atomic_weaker2(i64* nocapture %P, i64 %n64, i32 %n32, i16 %n16, i8 %n8) {
|
define void @write16To23AndThen24To31_atomic_weaker2(ptr nocapture %P, i64 %n64, i32 %n32, i16 %n16, i8 %n8) {
|
||||||
; CHECK-LABEL: @write16To23AndThen24To31_atomic_weaker2(
|
; CHECK-LABEL: @write16To23AndThen24To31_atomic_weaker2(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[BASE0:%.*]] = bitcast i64* [[P:%.*]] to i8*
|
; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 8 [[P:%.*]], i8 0, i64 16, i32 8)
|
||||||
; CHECK-NEXT: [[MYBASE0:%.*]] = getelementptr inbounds i8, i8* [[BASE0]], i64 0
|
; CHECK-NEXT: [[BASE64_2:%.*]] = getelementptr inbounds i64, ptr [[P]], i64 2
|
||||||
; CHECK-NEXT: tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 [[MYBASE0]], i8 0, i64 16, i32 8)
|
; CHECK-NEXT: [[BASE64_3:%.*]] = getelementptr inbounds i64, ptr [[P]], i64 3
|
||||||
; CHECK-NEXT: [[BASE64_2:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 2
|
; CHECK-NEXT: store atomic i64 3, ptr [[BASE64_2]] unordered, align 8
|
||||||
; CHECK-NEXT: [[BASE64_3:%.*]] = getelementptr inbounds i64, i64* [[P]], i64 3
|
; CHECK-NEXT: store i64 3, ptr [[BASE64_3]], align 8
|
||||||
; CHECK-NEXT: store atomic i64 3, i64* [[BASE64_2]] unordered, align 8
|
|
||||||
; CHECK-NEXT: store i64 3, i64* [[BASE64_3]], align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
%base0 = bitcast i64* %P to i8*
|
tail call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 8 %P, i8 0, i64 32, i32 8)
|
||||||
%mybase0 = getelementptr inbounds i8, i8* %base0, i64 0
|
|
||||||
tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 8 %mybase0, i8 0, i64 32, i32 8)
|
|
||||||
|
|
||||||
%base64_2 = getelementptr inbounds i64, i64* %P, i64 2
|
%base64_2 = getelementptr inbounds i64, ptr %P, i64 2
|
||||||
%base64_3 = getelementptr inbounds i64, i64* %P, i64 3
|
%base64_3 = getelementptr inbounds i64, ptr %P, i64 3
|
||||||
|
|
||||||
store atomic i64 3, i64* %base64_2 unordered, align 8
|
store atomic i64 3, ptr %base64_2 unordered, align 8
|
||||||
store i64 3, i64* %base64_3, align 8
|
store i64 3, ptr %base64_3, align 8
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @ow_end_align1(i8* nocapture %p) {
|
define void @ow_end_align1(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @ow_end_align1(
|
; CHECK-LABEL: @ow_end_align1(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, i8* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[P1]], i8 0, i64 27, i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[P1]], i8 0, i64 27, i1 false)
|
||||||
; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds i8, i8* [[P1]], i64 27
|
; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 27
|
||||||
; CHECK-NEXT: [[P2_I64:%.*]] = bitcast i8* [[P2]] to i64*
|
; CHECK-NEXT: store i64 1, ptr [[P2]], align 1
|
||||||
; CHECK-NEXT: store i64 1, i64* [[P2_I64]], align 1
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p1 = getelementptr inbounds i8, i8* %p, i64 1
|
%p1 = getelementptr inbounds i8, ptr %p, i64 1
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %p1, i8 0, i64 32, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %p1, i8 0, i64 32, i1 false)
|
||||||
%p2 = getelementptr inbounds i8, i8* %p1, i64 27
|
%p2 = getelementptr inbounds i8, ptr %p1, i64 27
|
||||||
%p2.i64 = bitcast i8* %p2 to i64*
|
store i64 1, ptr %p2, align 1
|
||||||
store i64 1, i64* %p2.i64, align 1
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @ow_end_align4(i8* nocapture %p) {
|
define void @ow_end_align4(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @ow_end_align4(
|
; CHECK-LABEL: @ow_end_align4(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, i8* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[P1]], i8 0, i64 28, i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[P1]], i8 0, i64 28, i1 false)
|
||||||
; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds i8, i8* [[P1]], i64 27
|
; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 27
|
||||||
; CHECK-NEXT: [[P2_I64:%.*]] = bitcast i8* [[P2]] to i64*
|
; CHECK-NEXT: store i64 1, ptr [[P2]], align 1
|
||||||
; CHECK-NEXT: store i64 1, i64* [[P2_I64]], align 1
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p1 = getelementptr inbounds i8, i8* %p, i64 1
|
%p1 = getelementptr inbounds i8, ptr %p, i64 1
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 4 %p1, i8 0, i64 32, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 4 %p1, i8 0, i64 32, i1 false)
|
||||||
%p2 = getelementptr inbounds i8, i8* %p1, i64 27
|
%p2 = getelementptr inbounds i8, ptr %p1, i64 27
|
||||||
%p2.i64 = bitcast i8* %p2 to i64*
|
store i64 1, ptr %p2, align 1
|
||||||
store i64 1, i64* %p2.i64, align 1
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @ow_end_align8(i8* nocapture %p) {
|
define void @ow_end_align8(ptr nocapture %p) {
|
||||||
; CHECK-LABEL: @ow_end_align8(
|
; CHECK-LABEL: @ow_end_align8(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, i8* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 8 [[P1]], i8 0, i64 32, i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[P1]], i8 0, i64 32, i1 false)
|
||||||
; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds i8, i8* [[P1]], i64 27
|
; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 27
|
||||||
; CHECK-NEXT: [[P2_I64:%.*]] = bitcast i8* [[P2]] to i64*
|
; CHECK-NEXT: store i64 1, ptr [[P2]], align 1
|
||||||
; CHECK-NEXT: store i64 1, i64* [[P2_I64]], align 1
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p1 = getelementptr inbounds i8, i8* %p, i64 1
|
%p1 = getelementptr inbounds i8, ptr %p, i64 1
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 8 %p1, i8 0, i64 32, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 8 %p1, i8 0, i64 32, i1 false)
|
||||||
%p2 = getelementptr inbounds i8, i8* %p1, i64 27
|
%p2 = getelementptr inbounds i8, ptr %p1, i64 27
|
||||||
%p2.i64 = bitcast i8* %p2 to i64*
|
store i64 1, ptr %p2, align 1
|
||||||
store i64 1, i64* %p2.i64, align 1
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,28 +4,25 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:1
|
||||||
|
|
||||||
; Ensure that the dead store is deleted in this case. It is wholely
|
; Ensure that the dead store is deleted in this case. It is wholely
|
||||||
; overwritten by the second store.
|
; overwritten by the second store.
|
||||||
define void @test1(i32 *%V) {
|
define void @test1(ptr %V) {
|
||||||
; CHECK-LABEL: @test1(
|
; CHECK-LABEL: @test1(
|
||||||
; CHECK-NEXT: store i32 1234567, i32* [[V:%.*]], align 4
|
; CHECK-NEXT: store i32 1234567, ptr [[V:%.*]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%V2 = bitcast i32* %V to i8* ; <i8*> [#uses=1]
|
store i8 0, ptr %V
|
||||||
store i8 0, i8* %V2
|
store i32 1234567, ptr %V
|
||||||
store i32 1234567, i32* %V
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Note that we could do better by merging the two stores into one.
|
; Note that we could do better by merging the two stores into one.
|
||||||
define void @test2(i32* %P) {
|
define void @test2(ptr %P) {
|
||||||
; CHECK-LABEL: @test2(
|
; CHECK-LABEL: @test2(
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: [[Q:%.*]] = bitcast i32* [[P]] to i16*
|
; CHECK-NEXT: store i16 1, ptr [[P]], align 2
|
||||||
; CHECK-NEXT: store i16 1, i16* [[Q]], align 2
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
%Q = bitcast i32* %P to i16*
|
store i16 1, ptr %P
|
||||||
store i16 1, i16* %Q
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,75 +30,70 @@ define void @test2(i32* %P) {
|
||||||
define i32 @test3(double %__x) {
|
define i32 @test3(double %__x) {
|
||||||
; CHECK-LABEL: @test3(
|
; CHECK-LABEL: @test3(
|
||||||
; CHECK-NEXT: [[__U:%.*]] = alloca { [3 x i32] }, align 4
|
; CHECK-NEXT: [[__U:%.*]] = alloca { [3 x i32] }, align 4
|
||||||
; CHECK-NEXT: [[TMP_1:%.*]] = bitcast { [3 x i32] }* [[__U]] to double*
|
; CHECK-NEXT: store double [[__X:%.*]], ptr [[__U]], align 8
|
||||||
; CHECK-NEXT: store double [[__X:%.*]], double* [[TMP_1]], align 8
|
; CHECK-NEXT: [[TMP_4:%.*]] = getelementptr { [3 x i32] }, ptr [[__U]], i32 0, i32 0, i32 1
|
||||||
; CHECK-NEXT: [[TMP_4:%.*]] = getelementptr { [3 x i32] }, { [3 x i32] }* [[__U]], i32 0, i32 0, i32 1
|
; CHECK-NEXT: [[TMP_5:%.*]] = load i32, ptr [[TMP_4]], align 4
|
||||||
; CHECK-NEXT: [[TMP_5:%.*]] = load i32, i32* [[TMP_4]], align 4
|
|
||||||
; CHECK-NEXT: [[TMP_6:%.*]] = icmp slt i32 [[TMP_5]], 0
|
; CHECK-NEXT: [[TMP_6:%.*]] = icmp slt i32 [[TMP_5]], 0
|
||||||
; CHECK-NEXT: [[TMP_7:%.*]] = zext i1 [[TMP_6]] to i32
|
; CHECK-NEXT: [[TMP_7:%.*]] = zext i1 [[TMP_6]] to i32
|
||||||
; CHECK-NEXT: ret i32 [[TMP_7]]
|
; CHECK-NEXT: ret i32 [[TMP_7]]
|
||||||
;
|
;
|
||||||
%__u = alloca { [3 x i32] }
|
%__u = alloca { [3 x i32] }
|
||||||
%tmp.1 = bitcast { [3 x i32] }* %__u to double*
|
store double %__x, ptr %__u
|
||||||
store double %__x, double* %tmp.1
|
%tmp.4 = getelementptr { [3 x i32] }, ptr %__u, i32 0, i32 0, i32 1
|
||||||
%tmp.4 = getelementptr { [3 x i32] }, { [3 x i32] }* %__u, i32 0, i32 0, i32 1
|
%tmp.5 = load i32, ptr %tmp.4
|
||||||
%tmp.5 = load i32, i32* %tmp.4
|
|
||||||
%tmp.6 = icmp slt i32 %tmp.5, 0
|
%tmp.6 = icmp slt i32 %tmp.5, 0
|
||||||
%tmp.7 = zext i1 %tmp.6 to i32
|
%tmp.7 = zext i1 %tmp.6 to i32
|
||||||
ret i32 %tmp.7
|
ret i32 %tmp.7
|
||||||
}
|
}
|
||||||
|
|
||||||
; PR6043
|
; PR6043
|
||||||
define void @test4(i8* %P) {
|
define void @test4(ptr %P) {
|
||||||
; CHECK-LABEL: @test4(
|
; CHECK-LABEL: @test4(
|
||||||
; CHECK-NEXT: [[Q:%.*]] = bitcast i8* [[P:%.*]] to double*
|
; CHECK-NEXT: store double 0.000000e+00, ptr [[P:%.*]], align 8
|
||||||
; CHECK-NEXT: store double 0.000000e+00, double* [[Q]], align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
|
|
||||||
store i8 19, i8* %P ;; dead
|
store i8 19, ptr %P ;; dead
|
||||||
%A = getelementptr i8, i8* %P, i32 3
|
%A = getelementptr i8, ptr %P, i32 3
|
||||||
|
|
||||||
store i8 42, i8* %A ;; dead
|
store i8 42, ptr %A ;; dead
|
||||||
|
|
||||||
%Q = bitcast i8* %P to double*
|
store double 0.0, ptr %P
|
||||||
store double 0.0, double* %Q
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; PR8657
|
; PR8657
|
||||||
declare void @test5a(i32*)
|
declare void @test5a(ptr)
|
||||||
define void @test5(i32 %i) nounwind ssp {
|
define void @test5(i32 %i) nounwind ssp {
|
||||||
; CHECK-LABEL: @test5(
|
; CHECK-LABEL: @test5(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: store i32 20, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 20, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: call void @test5a(i32* [[A]])
|
; CHECK-NEXT: call void @test5a(ptr [[A]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%A = alloca i32
|
%A = alloca i32
|
||||||
%B = bitcast i32* %A to i8*
|
%C = getelementptr i8, ptr %A, i32 %i
|
||||||
%C = getelementptr i8, i8* %B, i32 %i
|
store i8 10, ptr %C ;; Dead store to variable index.
|
||||||
store i8 10, i8* %C ;; Dead store to variable index.
|
store i32 20, ptr %A
|
||||||
store i32 20, i32* %A
|
|
||||||
|
|
||||||
call void @test5a(i32* %A)
|
call void @test5a(ptr %A)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @test5a_as1(i32*)
|
declare void @test5a_as1(ptr)
|
||||||
define void @test5_addrspacecast(i32 %i) nounwind ssp {
|
define void @test5_addrspacecast(i32 %i) nounwind ssp {
|
||||||
; CHECK-LABEL: @test5_addrspacecast(
|
; CHECK-LABEL: @test5_addrspacecast(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: store i32 20, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 20, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: call void @test5a(i32* [[A]])
|
; CHECK-NEXT: call void @test5a(ptr [[A]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%A = alloca i32
|
%A = alloca i32
|
||||||
%B = addrspacecast i32* %A to i8 addrspace(1)*
|
%B = addrspacecast ptr %A to ptr addrspace(1)
|
||||||
%C = getelementptr i8, i8 addrspace(1)* %B, i32 %i
|
%C = getelementptr i8, ptr addrspace(1) %B, i32 %i
|
||||||
store i8 10, i8 addrspace(1)* %C ;; Dead store to variable index.
|
store i8 10, ptr addrspace(1) %C ;; Dead store to variable index.
|
||||||
store i32 20, i32* %A
|
store i32 20, ptr %A
|
||||||
|
|
||||||
call void @test5a(i32* %A)
|
call void @test5a(ptr %A)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,25 +6,21 @@
|
||||||
;
|
;
|
||||||
; Better safe than sorry, do not assume anything about the padding for the
|
; Better safe than sorry, do not assume anything about the padding for the
|
||||||
; i28 store that has 32 bits as store size.
|
; i28 store that has 32 bits as store size.
|
||||||
define void @test1(i32* %p) {
|
define void @test1(ptr %p) {
|
||||||
; CHECK-LABEL: @test1(
|
; CHECK-LABEL: @test1(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32
|
; CHECK-NEXT: [[A:%.*]] = alloca i32
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast i32* [[A]] to i28*
|
; CHECK-NEXT: [[C1:%.*]] = getelementptr inbounds { i16, i16 }, ptr [[A]], i32 0, i32 1
|
||||||
; CHECK-NEXT: [[C:%.*]] = bitcast i32* [[A]] to { i16, i16 }*
|
; CHECK-NEXT: store i28 10, ptr [[A]]
|
||||||
; CHECK-NEXT: [[C1:%.*]] = getelementptr inbounds { i16, i16 }, { i16, i16 }* [[C]], i32 0, i32 1
|
; CHECK-NEXT: store i16 20, ptr [[C1]]
|
||||||
; CHECK-NEXT: store i28 10, i28* [[B]]
|
; CHECK-NEXT: call void @test1(ptr [[A]])
|
||||||
; CHECK-NEXT: store i16 20, i16* [[C1]]
|
|
||||||
; CHECK-NEXT: call void @test1(i32* [[A]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca i32
|
%a = alloca i32
|
||||||
%b = bitcast i32* %a to i28*
|
%c1 = getelementptr inbounds { i16, i16 }, ptr %a, i32 0, i32 1
|
||||||
%c = bitcast i32* %a to { i16, i16 }*
|
store i28 10, ptr %a
|
||||||
%c1 = getelementptr inbounds { i16, i16 }, { i16, i16 }* %c, i32 0, i32 1
|
store i16 20, ptr %c1
|
||||||
store i28 10, i28* %b
|
|
||||||
store i16 20, i16* %c1
|
|
||||||
|
|
||||||
call void @test1(i32* %a)
|
call void @test1(ptr %a)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,23 +29,19 @@ define void @test1(i32* %p) {
|
||||||
;
|
;
|
||||||
; Better safe than sorry, do not assume anything about the padding for the
|
; Better safe than sorry, do not assume anything about the padding for the
|
||||||
; i12 store that has 16 bits as store size.
|
; i12 store that has 16 bits as store size.
|
||||||
define void @test2(i32* %p) {
|
define void @test2(ptr %p) {
|
||||||
; CHECK-LABEL: @test2(
|
; CHECK-LABEL: @test2(
|
||||||
; CHECK-NEXT: [[U:%.*]] = alloca i32
|
; CHECK-NEXT: [[U:%.*]] = alloca i32
|
||||||
; CHECK-NEXT: [[A:%.*]] = bitcast i32* [[U]] to i32*
|
; CHECK-NEXT: store i32 -1, ptr [[U]]
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast i32* [[U]] to i12*
|
; CHECK-NEXT: store i12 20, ptr [[U]]
|
||||||
; CHECK-NEXT: store i32 -1, i32* [[A]]
|
; CHECK-NEXT: call void @test2(ptr [[U]])
|
||||||
; CHECK-NEXT: store i12 20, i12* [[B]]
|
|
||||||
; CHECK-NEXT: call void @test2(i32* [[U]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%u = alloca i32
|
%u = alloca i32
|
||||||
%a = bitcast i32* %u to i32*
|
store i32 -1, ptr %u
|
||||||
%b = bitcast i32* %u to i12*
|
store i12 20, ptr %u
|
||||||
store i32 -1, i32* %a
|
|
||||||
store i12 20, i12* %b
|
|
||||||
|
|
||||||
call void @test2(i32* %u)
|
call void @test2(ptr %u)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,19 +3,19 @@
|
||||||
|
|
||||||
; Both stores should be emitted because we can't tell if the gather aliases.
|
; Both stores should be emitted because we can't tell if the gather aliases.
|
||||||
|
|
||||||
define <4 x i32> @bar(<4 x i32> %arg, i32* %arg1) {
|
define <4 x i32> @bar(<4 x i32> %arg, ptr %arg1) {
|
||||||
; CHECK-LABEL: @bar(
|
; CHECK-LABEL: @bar(
|
||||||
; CHECK-NEXT: bb:
|
; CHECK-NEXT: bb:
|
||||||
; CHECK-NEXT: store i32 5, i32* [[ARG1:%.*]]
|
; CHECK-NEXT: store i32 5, ptr [[ARG1:%.*]]
|
||||||
; CHECK-NEXT: [[TMP:%.*]] = tail call <4 x i32> @llvm.x86.avx2.gather.d.d(<4 x i32> zeroinitializer, i8* null, <4 x i32> [[ARG:%.*]], <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, i8 1)
|
; CHECK-NEXT: [[TMP:%.*]] = tail call <4 x i32> @llvm.x86.avx2.gather.d.d(<4 x i32> zeroinitializer, ptr null, <4 x i32> [[ARG:%.*]], <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, i8 1)
|
||||||
; CHECK-NEXT: store i32 10, i32* [[ARG1]]
|
; CHECK-NEXT: store i32 10, ptr [[ARG1]]
|
||||||
; CHECK-NEXT: ret <4 x i32> [[TMP]]
|
; CHECK-NEXT: ret <4 x i32> [[TMP]]
|
||||||
;
|
;
|
||||||
bb:
|
bb:
|
||||||
store i32 5, i32* %arg1
|
store i32 5, ptr %arg1
|
||||||
%tmp = tail call <4 x i32> @llvm.x86.avx2.gather.d.d(<4 x i32> zeroinitializer, i8* null, <4 x i32> %arg, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, i8 1)
|
%tmp = tail call <4 x i32> @llvm.x86.avx2.gather.d.d(<4 x i32> zeroinitializer, ptr null, <4 x i32> %arg, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, i8 1)
|
||||||
store i32 10, i32* %arg1
|
store i32 10, ptr %arg1
|
||||||
ret <4 x i32> %tmp
|
ret <4 x i32> %tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
declare <4 x i32> @llvm.x86.avx2.gather.d.d(<4 x i32>, i8*, <4 x i32>, <4 x i32>, i8)
|
declare <4 x i32> @llvm.x86.avx2.gather.d.d(<4 x i32>, ptr, <4 x i32>, <4 x i32>, i8)
|
||||||
|
|
|
@ -5,36 +5,36 @@
|
||||||
|
|
||||||
define void @f() {
|
define void @f() {
|
||||||
; CHECK-LABEL: @f(
|
; CHECK-LABEL: @f(
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = call noalias i8* @_Znwm(i64 32)
|
; CHECK-NEXT: [[TMP1:%.*]] = call noalias ptr @_Znwm(i64 32)
|
||||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i8* [[TMP1]], @global
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt ptr [[TMP1]], @global
|
||||||
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP2]])
|
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP2]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%tmp1 = call noalias i8* @_Znwm(i64 32)
|
%tmp1 = call noalias ptr @_Znwm(i64 32)
|
||||||
%tmp2 = icmp ugt i8* %tmp1, @global
|
%tmp2 = icmp ugt ptr %tmp1, @global
|
||||||
call void @llvm.assume(i1 %tmp2)
|
call void @llvm.assume(i1 %tmp2)
|
||||||
store i8 0, i8* %tmp1, align 1
|
store i8 0, ptr %tmp1, align 1
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @f2() {
|
define void @f2() {
|
||||||
; CHECK-LABEL: @f2(
|
; CHECK-LABEL: @f2(
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = call noalias i8* @_Znwm(i64 32)
|
; CHECK-NEXT: [[TMP1:%.*]] = call noalias ptr @_Znwm(i64 32)
|
||||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i8* [[TMP1]], @global
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt ptr [[TMP1]], @global
|
||||||
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP2]])
|
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP2]])
|
||||||
; CHECK-NEXT: call void @quux(i8* @global)
|
; CHECK-NEXT: call void @quux(ptr @global)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%tmp1 = call noalias i8* @_Znwm(i64 32)
|
%tmp1 = call noalias ptr @_Znwm(i64 32)
|
||||||
%tmp2 = icmp ugt i8* %tmp1, @global
|
%tmp2 = icmp ugt ptr %tmp1, @global
|
||||||
call void @llvm.assume(i1 %tmp2)
|
call void @llvm.assume(i1 %tmp2)
|
||||||
store i8 0, i8* %tmp1, align 1
|
store i8 0, ptr %tmp1, align 1
|
||||||
call void @quux(i8* @global)
|
call void @quux(ptr @global)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i8* @_Znwm(i64)
|
declare ptr @_Znwm(i64)
|
||||||
|
|
||||||
declare void @llvm.assume(i1)
|
declare void @llvm.assume(i1)
|
||||||
|
|
||||||
declare void @quux(i8*)
|
declare void @quux(ptr)
|
||||||
|
|
|
@ -3,23 +3,17 @@
|
||||||
|
|
||||||
target datalayout = "e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128"
|
target datalayout = "e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128"
|
||||||
|
|
||||||
define void @widget(i8* %ptr) {
|
define void @widget(ptr %ptr) {
|
||||||
; CHECK-LABEL: @widget(
|
; CHECK-LABEL: @widget(
|
||||||
; CHECK-NEXT: bb:
|
; CHECK-NEXT: bb:
|
||||||
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[PTR:%.*]], i32 4
|
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i32 4
|
||||||
; CHECK-NEXT: [[PTR1_CAST:%.*]] = bitcast i8* [[PTR1]] to i32*
|
; CHECK-NEXT: store atomic i32 0, ptr [[PTR1]] monotonic, align 4
|
||||||
; CHECK-NEXT: store atomic i32 0, i32* [[PTR1_CAST]] monotonic, align 4
|
; CHECK-NEXT: store ptr null, ptr [[PTR]], align 4
|
||||||
; CHECK-NEXT: [[PTR2:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i32 0
|
|
||||||
; CHECK-NEXT: [[PTR2_CAST:%.*]] = bitcast i8* [[PTR2]] to i64**
|
|
||||||
; CHECK-NEXT: store i64* null, i64** [[PTR2_CAST]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
bb:
|
bb:
|
||||||
%ptr1 = getelementptr inbounds i8, i8* %ptr, i32 4
|
%ptr1 = getelementptr inbounds i8, ptr %ptr, i32 4
|
||||||
%ptr1.cast = bitcast i8* %ptr1 to i32*
|
store atomic i32 0, ptr %ptr1 monotonic, align 4
|
||||||
store atomic i32 0, i32* %ptr1.cast monotonic, align 4
|
store ptr null, ptr %ptr, align 4
|
||||||
%ptr2 = getelementptr inbounds i8, i8* %ptr, i32 0
|
|
||||||
%ptr2.cast = bitcast i8* %ptr2 to i64**
|
|
||||||
store i64* null, i64** %ptr2.cast, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,8 @@ define i32 @test9() {
|
||||||
; CHECK-LABEL: test9
|
; CHECK-LABEL: test9
|
||||||
; CHECK-NOT: store i32 0
|
; CHECK-NOT: store i32 0
|
||||||
; CHECK: store i32 1
|
; CHECK: store i32 1
|
||||||
store i32 0, i32* @x
|
store i32 0, ptr @x
|
||||||
%x = load atomic i32, i32* @y monotonic, align 4
|
%x = load atomic i32, ptr @y monotonic, align 4
|
||||||
store i32 1, i32* @x
|
store i32 1, ptr @x
|
||||||
ret i32 %x
|
ret i32 %x
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,40 +11,40 @@ target triple = "x86_64-apple-macosx10.7.0"
|
||||||
@x = common global i32 0, align 4
|
@x = common global i32 0, align 4
|
||||||
@y = common global i32 0, align 4
|
@y = common global i32 0, align 4
|
||||||
|
|
||||||
declare void @randomop(i32*)
|
declare void @randomop(ptr)
|
||||||
|
|
||||||
; DSE across unordered store (allowed)
|
; DSE across unordered store (allowed)
|
||||||
define void @test1() {
|
define void @test1() {
|
||||||
; CHECK-LABEL: @test1(
|
; CHECK-LABEL: @test1(
|
||||||
; CHECK-NEXT: store atomic i32 0, i32* @y unordered, align 4
|
; CHECK-NEXT: store atomic i32 0, ptr @y unordered, align 4
|
||||||
; CHECK-NEXT: store i32 1, i32* @x, align 4
|
; CHECK-NEXT: store i32 1, ptr @x, align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 0, i32* @x
|
store i32 0, ptr @x
|
||||||
store atomic i32 0, i32* @y unordered, align 4
|
store atomic i32 0, ptr @y unordered, align 4
|
||||||
store i32 1, i32* @x
|
store i32 1, ptr @x
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; DSE remove unordered store (allowed)
|
; DSE remove unordered store (allowed)
|
||||||
define void @test4() {
|
define void @test4() {
|
||||||
; CHECK-LABEL: @test4(
|
; CHECK-LABEL: @test4(
|
||||||
; CHECK-NEXT: store i32 1, i32* @x, align 4
|
; CHECK-NEXT: store i32 1, ptr @x, align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store atomic i32 0, i32* @x unordered, align 4
|
store atomic i32 0, ptr @x unordered, align 4
|
||||||
store i32 1, i32* @x
|
store i32 1, ptr @x
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; DSE unordered store overwriting non-atomic store (allowed)
|
; DSE unordered store overwriting non-atomic store (allowed)
|
||||||
define void @test5() {
|
define void @test5() {
|
||||||
; CHECK-LABEL: @test5(
|
; CHECK-LABEL: @test5(
|
||||||
; CHECK-NEXT: store atomic i32 1, i32* @x unordered, align 4
|
; CHECK-NEXT: store atomic i32 1, ptr @x unordered, align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 0, i32* @x
|
store i32 0, ptr @x
|
||||||
store atomic i32 1, i32* @x unordered, align 4
|
store atomic i32 1, ptr @x unordered, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,8 +53,8 @@ define void @test6() {
|
||||||
; CHECK-LABEL: @test6(
|
; CHECK-LABEL: @test6(
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%x = load atomic i32, i32* @x unordered, align 4
|
%x = load atomic i32, ptr @x unordered, align 4
|
||||||
store atomic i32 %x, i32* @x unordered, align 4
|
store atomic i32 %x, ptr @x unordered, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,11 +63,11 @@ define void @test6() {
|
||||||
define void @test7() {
|
define void @test7() {
|
||||||
; CHECK-LABEL: @test7(
|
; CHECK-LABEL: @test7(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: store atomic i32 0, i32* [[A]] seq_cst, align 4
|
; CHECK-NEXT: store atomic i32 0, ptr [[A]] seq_cst, align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca i32
|
%a = alloca i32
|
||||||
store atomic i32 0, i32* %a seq_cst, align 4
|
store atomic i32 0, ptr %a seq_cst, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,15 +76,15 @@ define void @test7() {
|
||||||
define i32 @test8() {
|
define i32 @test8() {
|
||||||
; CHECK-LABEL: @test8(
|
; CHECK-LABEL: @test8(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: call void @randomop(i32* [[A]])
|
; CHECK-NEXT: call void @randomop(ptr [[A]])
|
||||||
; CHECK-NEXT: store i32 0, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: [[X:%.*]] = load atomic i32, i32* @x seq_cst, align 4
|
; CHECK-NEXT: [[X:%.*]] = load atomic i32, ptr @x seq_cst, align 4
|
||||||
; CHECK-NEXT: ret i32 [[X]]
|
; CHECK-NEXT: ret i32 [[X]]
|
||||||
;
|
;
|
||||||
%a = alloca i32
|
%a = alloca i32
|
||||||
call void @randomop(i32* %a)
|
call void @randomop(ptr %a)
|
||||||
store i32 0, i32* %a, align 4
|
store i32 0, ptr %a, align 4
|
||||||
%x = load atomic i32, i32* @x seq_cst, align 4
|
%x = load atomic i32, ptr @x seq_cst, align 4
|
||||||
ret i32 %x
|
ret i32 %x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,53 +93,53 @@ define void @test10() {
|
||||||
; CHECK-LABEL: test10
|
; CHECK-LABEL: test10
|
||||||
; CHECK-NOT: store i32 0
|
; CHECK-NOT: store i32 0
|
||||||
; CHECK: store i32 1
|
; CHECK: store i32 1
|
||||||
store i32 0, i32* @x
|
store i32 0, ptr @x
|
||||||
store atomic i32 42, i32* @y monotonic, align 4
|
store atomic i32 42, ptr @y monotonic, align 4
|
||||||
store i32 1, i32* @x
|
store i32 1, ptr @x
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; DSE across monotonic load (forbidden since the eliminated store is atomic)
|
; DSE across monotonic load (forbidden since the eliminated store is atomic)
|
||||||
define i32 @test11() {
|
define i32 @test11() {
|
||||||
; CHECK-LABEL: @test11(
|
; CHECK-LABEL: @test11(
|
||||||
; CHECK-NEXT: store atomic i32 0, i32* @x monotonic, align 4
|
; CHECK-NEXT: store atomic i32 0, ptr @x monotonic, align 4
|
||||||
; CHECK-NEXT: [[X:%.*]] = load atomic i32, i32* @y monotonic, align 4
|
; CHECK-NEXT: [[X:%.*]] = load atomic i32, ptr @y monotonic, align 4
|
||||||
; CHECK-NEXT: store atomic i32 1, i32* @x monotonic, align 4
|
; CHECK-NEXT: store atomic i32 1, ptr @x monotonic, align 4
|
||||||
; CHECK-NEXT: ret i32 [[X]]
|
; CHECK-NEXT: ret i32 [[X]]
|
||||||
;
|
;
|
||||||
store atomic i32 0, i32* @x monotonic, align 4
|
store atomic i32 0, ptr @x monotonic, align 4
|
||||||
%x = load atomic i32, i32* @y monotonic, align 4
|
%x = load atomic i32, ptr @y monotonic, align 4
|
||||||
store atomic i32 1, i32* @x monotonic, align 4
|
store atomic i32 1, ptr @x monotonic, align 4
|
||||||
ret i32 %x
|
ret i32 %x
|
||||||
}
|
}
|
||||||
|
|
||||||
; DSE across monotonic store (forbidden since the eliminated store is atomic)
|
; DSE across monotonic store (forbidden since the eliminated store is atomic)
|
||||||
define void @test12() {
|
define void @test12() {
|
||||||
; CHECK-LABEL: @test12(
|
; CHECK-LABEL: @test12(
|
||||||
; CHECK-NEXT: store atomic i32 0, i32* @x monotonic, align 4
|
; CHECK-NEXT: store atomic i32 0, ptr @x monotonic, align 4
|
||||||
; CHECK-NEXT: store atomic i32 42, i32* @y monotonic, align 4
|
; CHECK-NEXT: store atomic i32 42, ptr @y monotonic, align 4
|
||||||
; CHECK-NEXT: store atomic i32 1, i32* @x monotonic, align 4
|
; CHECK-NEXT: store atomic i32 1, ptr @x monotonic, align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store atomic i32 0, i32* @x monotonic, align 4
|
store atomic i32 0, ptr @x monotonic, align 4
|
||||||
store atomic i32 42, i32* @y monotonic, align 4
|
store atomic i32 42, ptr @y monotonic, align 4
|
||||||
store atomic i32 1, i32* @x monotonic, align 4
|
store atomic i32 1, ptr @x monotonic, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; But DSE is not allowed across a release-acquire pair.
|
; But DSE is not allowed across a release-acquire pair.
|
||||||
define i32 @test15() {
|
define i32 @test15() {
|
||||||
; CHECK-LABEL: @test15(
|
; CHECK-LABEL: @test15(
|
||||||
; CHECK-NEXT: store i32 0, i32* @x, align 4
|
; CHECK-NEXT: store i32 0, ptr @x, align 4
|
||||||
; CHECK-NEXT: store atomic i32 0, i32* @y release, align 4
|
; CHECK-NEXT: store atomic i32 0, ptr @y release, align 4
|
||||||
; CHECK-NEXT: [[X:%.*]] = load atomic i32, i32* @y acquire, align 4
|
; CHECK-NEXT: [[X:%.*]] = load atomic i32, ptr @y acquire, align 4
|
||||||
; CHECK-NEXT: store i32 1, i32* @x, align 4
|
; CHECK-NEXT: store i32 1, ptr @x, align 4
|
||||||
; CHECK-NEXT: ret i32 [[X]]
|
; CHECK-NEXT: ret i32 [[X]]
|
||||||
;
|
;
|
||||||
store i32 0, i32* @x
|
store i32 0, ptr @x
|
||||||
store atomic i32 0, i32* @y release, align 4
|
store atomic i32 0, ptr @y release, align 4
|
||||||
%x = load atomic i32, i32* @y acquire, align 4
|
%x = load atomic i32, ptr @y acquire, align 4
|
||||||
store i32 1, i32* @x
|
store i32 1, ptr @x
|
||||||
ret i32 %x
|
ret i32 %x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,181 +149,181 @@ define i32 @test15() {
|
||||||
; Be conservative, do not kill regular store.
|
; Be conservative, do not kill regular store.
|
||||||
define i64 @test_atomicrmw_0() {
|
define i64 @test_atomicrmw_0() {
|
||||||
; CHECK-LABEL: @test_atomicrmw_0(
|
; CHECK-LABEL: @test_atomicrmw_0(
|
||||||
; CHECK-NEXT: store i64 1, i64* @z, align 8
|
; CHECK-NEXT: store i64 1, ptr @z, align 8
|
||||||
; CHECK-NEXT: [[RES:%.*]] = atomicrmw add i64* @z, i64 -1 monotonic
|
; CHECK-NEXT: [[RES:%.*]] = atomicrmw add ptr @z, i64 -1 monotonic
|
||||||
; CHECK-NEXT: ret i64 [[RES]]
|
; CHECK-NEXT: ret i64 [[RES]]
|
||||||
;
|
;
|
||||||
store i64 1, i64* @z
|
store i64 1, ptr @z
|
||||||
%res = atomicrmw add i64* @z, i64 -1 monotonic
|
%res = atomicrmw add ptr @z, i64 -1 monotonic
|
||||||
ret i64 %res
|
ret i64 %res
|
||||||
}
|
}
|
||||||
|
|
||||||
; Be conservative, do not kill regular store.
|
; Be conservative, do not kill regular store.
|
||||||
define i64 @test_atomicrmw_1() {
|
define i64 @test_atomicrmw_1() {
|
||||||
; CHECK-LABEL: @test_atomicrmw_1(
|
; CHECK-LABEL: @test_atomicrmw_1(
|
||||||
; CHECK-NEXT: store i64 1, i64* @z, align 8
|
; CHECK-NEXT: store i64 1, ptr @z, align 8
|
||||||
; CHECK-NEXT: [[RES:%.*]] = atomicrmw add i64* @z, i64 -1 acq_rel
|
; CHECK-NEXT: [[RES:%.*]] = atomicrmw add ptr @z, i64 -1 acq_rel
|
||||||
; CHECK-NEXT: ret i64 [[RES]]
|
; CHECK-NEXT: ret i64 [[RES]]
|
||||||
;
|
;
|
||||||
store i64 1, i64* @z
|
store i64 1, ptr @z
|
||||||
%res = atomicrmw add i64* @z, i64 -1 acq_rel
|
%res = atomicrmw add ptr @z, i64 -1 acq_rel
|
||||||
ret i64 %res
|
ret i64 %res
|
||||||
}
|
}
|
||||||
|
|
||||||
; Monotonic atomicrmw should not block eliminating no-aliasing stores.
|
; Monotonic atomicrmw should not block eliminating no-aliasing stores.
|
||||||
define i64 @test_atomicrmw_2() {
|
define i64 @test_atomicrmw_2() {
|
||||||
; CHECK-LABEL: @test_atomicrmw_2(
|
; CHECK-LABEL: @test_atomicrmw_2(
|
||||||
; CHECK-NEXT: [[RES:%.*]] = atomicrmw add i64* @a, i64 -1 monotonic
|
; CHECK-NEXT: [[RES:%.*]] = atomicrmw add ptr @a, i64 -1 monotonic
|
||||||
; CHECK-NEXT: store i64 2, i64* @z, align 8
|
; CHECK-NEXT: store i64 2, ptr @z, align 8
|
||||||
; CHECK-NEXT: ret i64 [[RES]]
|
; CHECK-NEXT: ret i64 [[RES]]
|
||||||
;
|
;
|
||||||
store i64 1, i64* @z
|
store i64 1, ptr @z
|
||||||
%res = atomicrmw add i64* @a, i64 -1 monotonic
|
%res = atomicrmw add ptr @a, i64 -1 monotonic
|
||||||
store i64 2, i64* @z
|
store i64 2, ptr @z
|
||||||
ret i64 %res
|
ret i64 %res
|
||||||
}
|
}
|
||||||
|
|
||||||
; Be conservative, do not eliminate stores across atomic operations > monotonic.
|
; Be conservative, do not eliminate stores across atomic operations > monotonic.
|
||||||
define i64 @test_atomicrmw_3() {
|
define i64 @test_atomicrmw_3() {
|
||||||
; CHECK-LABEL: @test_atomicrmw_3(
|
; CHECK-LABEL: @test_atomicrmw_3(
|
||||||
; CHECK-NEXT: store i64 1, i64* @z, align 8
|
; CHECK-NEXT: store i64 1, ptr @z, align 8
|
||||||
; CHECK-NEXT: [[RES:%.*]] = atomicrmw add i64* @a, i64 -1 release
|
; CHECK-NEXT: [[RES:%.*]] = atomicrmw add ptr @a, i64 -1 release
|
||||||
; CHECK-NEXT: store i64 2, i64* @z, align 8
|
; CHECK-NEXT: store i64 2, ptr @z, align 8
|
||||||
; CHECK-NEXT: ret i64 [[RES]]
|
; CHECK-NEXT: ret i64 [[RES]]
|
||||||
;
|
;
|
||||||
store i64 1, i64* @z
|
store i64 1, ptr @z
|
||||||
%res = atomicrmw add i64* @a, i64 -1 release
|
%res = atomicrmw add ptr @a, i64 -1 release
|
||||||
store i64 2, i64* @z
|
store i64 2, ptr @z
|
||||||
ret i64 %res
|
ret i64 %res
|
||||||
}
|
}
|
||||||
|
|
||||||
; Be conservative, do not eliminate may-alias stores.
|
; Be conservative, do not eliminate may-alias stores.
|
||||||
define i64 @test_atomicrmw_4(i64* %ptr) {
|
define i64 @test_atomicrmw_4(ptr %ptr) {
|
||||||
; CHECK-LABEL: @test_atomicrmw_4(
|
; CHECK-LABEL: @test_atomicrmw_4(
|
||||||
; CHECK-NEXT: store i64 1, i64* @z, align 8
|
; CHECK-NEXT: store i64 1, ptr @z, align 8
|
||||||
; CHECK-NEXT: [[RES:%.*]] = atomicrmw add i64* [[PTR:%.*]], i64 -1 monotonic
|
; CHECK-NEXT: [[RES:%.*]] = atomicrmw add ptr [[PTR:%.*]], i64 -1 monotonic
|
||||||
; CHECK-NEXT: store i64 2, i64* @z, align 8
|
; CHECK-NEXT: store i64 2, ptr @z, align 8
|
||||||
; CHECK-NEXT: ret i64 [[RES]]
|
; CHECK-NEXT: ret i64 [[RES]]
|
||||||
;
|
;
|
||||||
store i64 1, i64* @z
|
store i64 1, ptr @z
|
||||||
%res = atomicrmw add i64* %ptr, i64 -1 monotonic
|
%res = atomicrmw add ptr %ptr, i64 -1 monotonic
|
||||||
store i64 2, i64* @z
|
store i64 2, ptr @z
|
||||||
ret i64 %res
|
ret i64 %res
|
||||||
}
|
}
|
||||||
|
|
||||||
; Be conservative, do not eliminate aliasing stores.
|
; Be conservative, do not eliminate aliasing stores.
|
||||||
define i64 @test_atomicrmw_5() {
|
define i64 @test_atomicrmw_5() {
|
||||||
; CHECK-LABEL: @test_atomicrmw_5(
|
; CHECK-LABEL: @test_atomicrmw_5(
|
||||||
; CHECK-NEXT: store i64 1, i64* @z, align 8
|
; CHECK-NEXT: store i64 1, ptr @z, align 8
|
||||||
; CHECK-NEXT: [[RES:%.*]] = atomicrmw add i64* @z, i64 -1 monotonic
|
; CHECK-NEXT: [[RES:%.*]] = atomicrmw add ptr @z, i64 -1 monotonic
|
||||||
; CHECK-NEXT: store i64 2, i64* @z, align 8
|
; CHECK-NEXT: store i64 2, ptr @z, align 8
|
||||||
; CHECK-NEXT: ret i64 [[RES]]
|
; CHECK-NEXT: ret i64 [[RES]]
|
||||||
;
|
;
|
||||||
store i64 1, i64* @z
|
store i64 1, ptr @z
|
||||||
%res = atomicrmw add i64* @z, i64 -1 monotonic
|
%res = atomicrmw add ptr @z, i64 -1 monotonic
|
||||||
store i64 2, i64* @z
|
store i64 2, ptr @z
|
||||||
ret i64 %res
|
ret i64 %res
|
||||||
}
|
}
|
||||||
|
|
||||||
; Be conservative, do not eliminate non-monotonic cmpxchg.
|
; Be conservative, do not eliminate non-monotonic cmpxchg.
|
||||||
define { i32, i1} @test_cmpxchg_1() {
|
define { i32, i1} @test_cmpxchg_1() {
|
||||||
; CHECK-LABEL: @test_cmpxchg_1(
|
; CHECK-LABEL: @test_cmpxchg_1(
|
||||||
; CHECK-NEXT: store i32 1, i32* @x, align 4
|
; CHECK-NEXT: store i32 1, ptr @x, align 4
|
||||||
; CHECK-NEXT: [[RET:%.*]] = cmpxchg volatile i32* @x, i32 10, i32 20 seq_cst monotonic
|
; CHECK-NEXT: [[RET:%.*]] = cmpxchg volatile ptr @x, i32 10, i32 20 seq_cst monotonic
|
||||||
; CHECK-NEXT: store i32 2, i32* @x, align 4
|
; CHECK-NEXT: store i32 2, ptr @x, align 4
|
||||||
; CHECK-NEXT: ret { i32, i1 } [[RET]]
|
; CHECK-NEXT: ret { i32, i1 } [[RET]]
|
||||||
;
|
;
|
||||||
store i32 1, i32* @x
|
store i32 1, ptr @x
|
||||||
%ret = cmpxchg volatile i32* @x, i32 10, i32 20 seq_cst monotonic
|
%ret = cmpxchg volatile ptr @x, i32 10, i32 20 seq_cst monotonic
|
||||||
store i32 2, i32* @x
|
store i32 2, ptr @x
|
||||||
ret { i32, i1 } %ret
|
ret { i32, i1 } %ret
|
||||||
}
|
}
|
||||||
|
|
||||||
; Monotonic cmpxchg should not block DSE for non-aliasing stores.
|
; Monotonic cmpxchg should not block DSE for non-aliasing stores.
|
||||||
define { i32, i1} @test_cmpxchg_2() {
|
define { i32, i1} @test_cmpxchg_2() {
|
||||||
; CHECK-LABEL: @test_cmpxchg_2(
|
; CHECK-LABEL: @test_cmpxchg_2(
|
||||||
; CHECK-NEXT: [[RET:%.*]] = cmpxchg volatile i32* @y, i32 10, i32 20 monotonic monotonic
|
; CHECK-NEXT: [[RET:%.*]] = cmpxchg volatile ptr @y, i32 10, i32 20 monotonic monotonic
|
||||||
; CHECK-NEXT: store i32 2, i32* @x, align 4
|
; CHECK-NEXT: store i32 2, ptr @x, align 4
|
||||||
; CHECK-NEXT: ret { i32, i1 } [[RET]]
|
; CHECK-NEXT: ret { i32, i1 } [[RET]]
|
||||||
;
|
;
|
||||||
store i32 1, i32* @x
|
store i32 1, ptr @x
|
||||||
%ret = cmpxchg volatile i32* @y, i32 10, i32 20 monotonic monotonic
|
%ret = cmpxchg volatile ptr @y, i32 10, i32 20 monotonic monotonic
|
||||||
store i32 2, i32* @x
|
store i32 2, ptr @x
|
||||||
ret { i32, i1 } %ret
|
ret { i32, i1 } %ret
|
||||||
}
|
}
|
||||||
|
|
||||||
; Be conservative, do not eliminate non-monotonic cmpxchg.
|
; Be conservative, do not eliminate non-monotonic cmpxchg.
|
||||||
define { i32, i1} @test_cmpxchg_3() {
|
define { i32, i1} @test_cmpxchg_3() {
|
||||||
; CHECK-LABEL: @test_cmpxchg_3(
|
; CHECK-LABEL: @test_cmpxchg_3(
|
||||||
; CHECK-NEXT: store i32 1, i32* @x, align 4
|
; CHECK-NEXT: store i32 1, ptr @x, align 4
|
||||||
; CHECK-NEXT: [[RET:%.*]] = cmpxchg volatile i32* @y, i32 10, i32 20 seq_cst seq_cst
|
; CHECK-NEXT: [[RET:%.*]] = cmpxchg volatile ptr @y, i32 10, i32 20 seq_cst seq_cst
|
||||||
; CHECK-NEXT: store i32 2, i32* @x, align 4
|
; CHECK-NEXT: store i32 2, ptr @x, align 4
|
||||||
; CHECK-NEXT: ret { i32, i1 } [[RET]]
|
; CHECK-NEXT: ret { i32, i1 } [[RET]]
|
||||||
;
|
;
|
||||||
store i32 1, i32* @x
|
store i32 1, ptr @x
|
||||||
%ret = cmpxchg volatile i32* @y, i32 10, i32 20 seq_cst seq_cst
|
%ret = cmpxchg volatile ptr @y, i32 10, i32 20 seq_cst seq_cst
|
||||||
store i32 2, i32* @x
|
store i32 2, ptr @x
|
||||||
ret { i32, i1 } %ret
|
ret { i32, i1 } %ret
|
||||||
}
|
}
|
||||||
|
|
||||||
; Be conservative, do not eliminate may-alias stores.
|
; Be conservative, do not eliminate may-alias stores.
|
||||||
define { i32, i1} @test_cmpxchg_4(i32* %ptr) {
|
define { i32, i1} @test_cmpxchg_4(ptr %ptr) {
|
||||||
; CHECK-LABEL: @test_cmpxchg_4(
|
; CHECK-LABEL: @test_cmpxchg_4(
|
||||||
; CHECK-NEXT: store i32 1, i32* @x, align 4
|
; CHECK-NEXT: store i32 1, ptr @x, align 4
|
||||||
; CHECK-NEXT: [[RET:%.*]] = cmpxchg volatile i32* [[PTR:%.*]], i32 10, i32 20 monotonic monotonic
|
; CHECK-NEXT: [[RET:%.*]] = cmpxchg volatile ptr [[PTR:%.*]], i32 10, i32 20 monotonic monotonic
|
||||||
; CHECK-NEXT: store i32 2, i32* @x, align 4
|
; CHECK-NEXT: store i32 2, ptr @x, align 4
|
||||||
; CHECK-NEXT: ret { i32, i1 } [[RET]]
|
; CHECK-NEXT: ret { i32, i1 } [[RET]]
|
||||||
;
|
;
|
||||||
store i32 1, i32* @x
|
store i32 1, ptr @x
|
||||||
%ret = cmpxchg volatile i32* %ptr, i32 10, i32 20 monotonic monotonic
|
%ret = cmpxchg volatile ptr %ptr, i32 10, i32 20 monotonic monotonic
|
||||||
store i32 2, i32* @x
|
store i32 2, ptr @x
|
||||||
ret { i32, i1 } %ret
|
ret { i32, i1 } %ret
|
||||||
}
|
}
|
||||||
|
|
||||||
; Be conservative, do not eliminate alias stores.
|
; Be conservative, do not eliminate alias stores.
|
||||||
define { i32, i1} @test_cmpxchg_5(i32* %ptr) {
|
define { i32, i1} @test_cmpxchg_5(ptr %ptr) {
|
||||||
; CHECK-LABEL: @test_cmpxchg_5(
|
; CHECK-LABEL: @test_cmpxchg_5(
|
||||||
; CHECK-NEXT: store i32 1, i32* @x, align 4
|
; CHECK-NEXT: store i32 1, ptr @x, align 4
|
||||||
; CHECK-NEXT: [[RET:%.*]] = cmpxchg volatile i32* @x, i32 10, i32 20 monotonic monotonic
|
; CHECK-NEXT: [[RET:%.*]] = cmpxchg volatile ptr @x, i32 10, i32 20 monotonic monotonic
|
||||||
; CHECK-NEXT: store i32 2, i32* @x, align 4
|
; CHECK-NEXT: store i32 2, ptr @x, align 4
|
||||||
; CHECK-NEXT: ret { i32, i1 } [[RET]]
|
; CHECK-NEXT: ret { i32, i1 } [[RET]]
|
||||||
;
|
;
|
||||||
store i32 1, i32* @x
|
store i32 1, ptr @x
|
||||||
%ret = cmpxchg volatile i32* @x, i32 10, i32 20 monotonic monotonic
|
%ret = cmpxchg volatile ptr @x, i32 10, i32 20 monotonic monotonic
|
||||||
store i32 2, i32* @x
|
store i32 2, ptr @x
|
||||||
ret { i32, i1 } %ret
|
ret { i32, i1 } %ret
|
||||||
}
|
}
|
||||||
|
|
||||||
; **** Noop load->store tests **************************************************
|
; **** Noop load->store tests **************************************************
|
||||||
|
|
||||||
; We can optimize unordered atomic loads or stores.
|
; We can optimize unordered atomic loads or stores.
|
||||||
define void @test_load_atomic(i32* %Q) {
|
define void @test_load_atomic(ptr %Q) {
|
||||||
; CHECK-LABEL: @test_load_atomic(
|
; CHECK-LABEL: @test_load_atomic(
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = load atomic i32, i32* %Q unordered, align 4
|
%a = load atomic i32, ptr %Q unordered, align 4
|
||||||
store atomic i32 %a, i32* %Q unordered, align 4
|
store atomic i32 %a, ptr %Q unordered, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; We can optimize unordered atomic loads or stores.
|
; We can optimize unordered atomic loads or stores.
|
||||||
define void @test_store_atomic(i32* %Q) {
|
define void @test_store_atomic(ptr %Q) {
|
||||||
; CHECK-LABEL: @test_store_atomic(
|
; CHECK-LABEL: @test_store_atomic(
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = load i32, i32* %Q
|
%a = load i32, ptr %Q
|
||||||
store atomic i32 %a, i32* %Q unordered, align 4
|
store atomic i32 %a, ptr %Q unordered, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; We can NOT optimize release atomic loads or stores.
|
; We can NOT optimize release atomic loads or stores.
|
||||||
define void @test_store_atomic_release(i32* %Q) {
|
define void @test_store_atomic_release(ptr %Q) {
|
||||||
; CHECK-LABEL: @test_store_atomic_release(
|
; CHECK-LABEL: @test_store_atomic_release(
|
||||||
; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[Q:%.*]], align 4
|
; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[Q:%.*]], align 4
|
||||||
; CHECK-NEXT: store atomic i32 [[A]], i32* [[Q]] release, align 4
|
; CHECK-NEXT: store atomic i32 [[A]], ptr [[Q]] release, align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = load i32, i32* %Q
|
%a = load i32, ptr %Q
|
||||||
store atomic i32 %a, i32* %Q release, align 4
|
store atomic i32 %a, ptr %Q release, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,156 +1,153 @@
|
||||||
; RUN: opt < %s -basic-aa -dse -S | FileCheck %s
|
; RUN: opt < %s -basic-aa -dse -S | FileCheck %s
|
||||||
|
|
||||||
declare noalias i8* @calloc(i64, i64) inaccessiblememonly allockind("alloc,zeroed")
|
declare noalias ptr @calloc(i64, i64) inaccessiblememonly allockind("alloc,zeroed")
|
||||||
|
|
||||||
define i32* @test1() {
|
define ptr @test1() {
|
||||||
; CHECK-LABEL: test1
|
; CHECK-LABEL: test1
|
||||||
%1 = tail call noalias i8* @calloc(i64 1, i64 4)
|
%1 = tail call noalias ptr @calloc(i64 1, i64 4)
|
||||||
%2 = bitcast i8* %1 to i32*
|
|
||||||
; This store is dead and should be removed
|
; This store is dead and should be removed
|
||||||
store i32 0, i32* %2, align 4
|
store i32 0, ptr %1, align 4
|
||||||
; CHECK-NOT: store i32 0, i32* %2, align 4
|
; CHECK-NOT: store i32 0, ptr %1, align 4
|
||||||
ret i32* %2
|
ret ptr %1
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32* @test2() {
|
define ptr @test2() {
|
||||||
; CHECK-LABEL: test2
|
; CHECK-LABEL: test2
|
||||||
%1 = tail call noalias i8* @calloc(i64 1, i64 4)
|
%1 = tail call noalias ptr @calloc(i64 1, i64 4)
|
||||||
%2 = bitcast i8* %1 to i32*
|
%2 = getelementptr i32, ptr %1, i32 5
|
||||||
%3 = getelementptr i32, i32* %2, i32 5
|
store i32 0, ptr %2, align 4
|
||||||
store i32 0, i32* %3, align 4
|
; CHECK-NOT: store i32 0, ptr %1, align 4
|
||||||
; CHECK-NOT: store i32 0, i32* %2, align 4
|
ret ptr %1
|
||||||
ret i32* %2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32* @test3(i32 *%arg) {
|
define ptr @test3(ptr %arg) {
|
||||||
; CHECK-LABEL: test3
|
; CHECK-LABEL: test3
|
||||||
store i32 0, i32* %arg, align 4
|
store i32 0, ptr %arg, align 4
|
||||||
; CHECK: store i32 0, i32* %arg, align 4
|
; CHECK: store i32 0, ptr %arg, align 4
|
||||||
ret i32* %arg
|
ret ptr %arg
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @clobber_memory(i8*)
|
declare void @clobber_memory(ptr)
|
||||||
define i8* @test4() {
|
define ptr @test4() {
|
||||||
; CHECK-LABEL: test4
|
; CHECK-LABEL: test4
|
||||||
%1 = tail call noalias i8* @calloc(i64 1, i64 4)
|
%1 = tail call noalias ptr @calloc(i64 1, i64 4)
|
||||||
call void @clobber_memory(i8* %1)
|
call void @clobber_memory(ptr %1)
|
||||||
store i8 0, i8* %1, align 4
|
store i8 0, ptr %1, align 4
|
||||||
; CHECK: store i8 0, i8* %1, align 4
|
; CHECK: store i8 0, ptr %1, align 4
|
||||||
ret i8* %1
|
ret ptr %1
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32* @test5() {
|
define ptr @test5() {
|
||||||
; CHECK-LABEL: test5
|
; CHECK-LABEL: test5
|
||||||
%1 = tail call noalias i8* @calloc(i64 1, i64 4)
|
%1 = tail call noalias ptr @calloc(i64 1, i64 4)
|
||||||
%2 = bitcast i8* %1 to i32*
|
store volatile i32 0, ptr %1, align 4
|
||||||
store volatile i32 0, i32* %2, align 4
|
; CHECK: store volatile i32 0, ptr %1, align 4
|
||||||
; CHECK: store volatile i32 0, i32* %2, align 4
|
ret ptr %1
|
||||||
ret i32* %2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define i8* @test6() {
|
define ptr @test6() {
|
||||||
; CHECK-LABEL: test6
|
; CHECK-LABEL: test6
|
||||||
%1 = tail call noalias i8* @calloc(i64 1, i64 4)
|
%1 = tail call noalias ptr @calloc(i64 1, i64 4)
|
||||||
store i8 5, i8* %1, align 4
|
store i8 5, ptr %1, align 4
|
||||||
; CHECK: store i8 5, i8* %1, align 4
|
; CHECK: store i8 5, ptr %1, align 4
|
||||||
ret i8* %1
|
ret ptr %1
|
||||||
}
|
}
|
||||||
|
|
||||||
define i8* @test7(i8 %arg) {
|
define ptr @test7(i8 %arg) {
|
||||||
; CHECK-LABEL: test7
|
; CHECK-LABEL: test7
|
||||||
%1 = tail call noalias i8* @calloc(i64 1, i64 4)
|
%1 = tail call noalias ptr @calloc(i64 1, i64 4)
|
||||||
store i8 %arg, i8* %1, align 4
|
store i8 %arg, ptr %1, align 4
|
||||||
; CHECK: store i8 %arg, i8* %1, align 4
|
; CHECK: store i8 %arg, ptr %1, align 4
|
||||||
ret i8* %1
|
ret ptr %1
|
||||||
}
|
}
|
||||||
|
|
||||||
define i8* @test8() {
|
define ptr @test8() {
|
||||||
; CHECK-LABEL: test8
|
; CHECK-LABEL: test8
|
||||||
; CHECK-NOT: store
|
; CHECK-NOT: store
|
||||||
%p = tail call noalias i8* @calloc(i64 1, i64 4)
|
%p = tail call noalias ptr @calloc(i64 1, i64 4)
|
||||||
store i8 0, i8* %p, align 1
|
store i8 0, ptr %p, align 1
|
||||||
%p.1 = getelementptr i8, i8* %p, i32 1
|
%p.1 = getelementptr i8, ptr %p, i32 1
|
||||||
store i8 0, i8* %p.1, align 1
|
store i8 0, ptr %p.1, align 1
|
||||||
%p.3 = getelementptr i8, i8* %p, i32 3
|
%p.3 = getelementptr i8, ptr %p, i32 3
|
||||||
store i8 0, i8* %p.3, align 1
|
store i8 0, ptr %p.3, align 1
|
||||||
%p.2 = getelementptr i8, i8* %p, i32 2
|
%p.2 = getelementptr i8, ptr %p, i32 2
|
||||||
store i8 0, i8* %p.2, align 1
|
store i8 0, ptr %p.2, align 1
|
||||||
ret i8* %p
|
ret ptr %p
|
||||||
}
|
}
|
||||||
|
|
||||||
define i8* @test9() {
|
define ptr @test9() {
|
||||||
; CHECK-LABEL: test9
|
; CHECK-LABEL: test9
|
||||||
; CHECK-NEXT: %p = tail call noalias i8* @calloc(i64 1, i64 4)
|
; CHECK-NEXT: %p = tail call noalias ptr @calloc(i64 1, i64 4)
|
||||||
; CHECK-NEXT: store i8 5, i8* %p, align 1
|
; CHECK-NEXT: store i8 5, ptr %p, align 1
|
||||||
; CHECK-NEXT: ret i8* %p
|
; CHECK-NEXT: ret ptr %p
|
||||||
|
|
||||||
%p = tail call noalias i8* @calloc(i64 1, i64 4)
|
%p = tail call noalias ptr @calloc(i64 1, i64 4)
|
||||||
store i8 5, i8* %p, align 1
|
store i8 5, ptr %p, align 1
|
||||||
%p.1 = getelementptr i8, i8* %p, i32 1
|
%p.1 = getelementptr i8, ptr %p, i32 1
|
||||||
store i8 0, i8* %p.1, align 1
|
store i8 0, ptr %p.1, align 1
|
||||||
%p.3 = getelementptr i8, i8* %p, i32 3
|
%p.3 = getelementptr i8, ptr %p, i32 3
|
||||||
store i8 0, i8* %p.3, align 1
|
store i8 0, ptr %p.3, align 1
|
||||||
%p.2 = getelementptr i8, i8* %p, i32 2
|
%p.2 = getelementptr i8, ptr %p, i32 2
|
||||||
store i8 0, i8* %p.2, align 1
|
store i8 0, ptr %p.2, align 1
|
||||||
ret i8* %p
|
ret ptr %p
|
||||||
}
|
}
|
||||||
|
|
||||||
define i8* @test10() {
|
define ptr @test10() {
|
||||||
; CHECK-LABEL: @test10(
|
; CHECK-LABEL: @test10(
|
||||||
; CHECK-NEXT: [[P:%.*]] = tail call noalias i8* @calloc(i64 1, i64 4)
|
; CHECK-NEXT: [[P:%.*]] = tail call noalias ptr @calloc(i64 1, i64 4)
|
||||||
; CHECK-NEXT: [[P_3:%.*]] = getelementptr i8, i8* [[P]], i32 3
|
; CHECK-NEXT: [[P_3:%.*]] = getelementptr i8, ptr [[P]], i32 3
|
||||||
; CHECK-NEXT: store i8 5, i8* [[P_3]], align 1
|
; CHECK-NEXT: store i8 5, ptr [[P_3]], align 1
|
||||||
; CHECK-NEXT: ret i8* [[P]]
|
; CHECK-NEXT: ret ptr [[P]]
|
||||||
;
|
;
|
||||||
|
|
||||||
%p = tail call noalias i8* @calloc(i64 1, i64 4)
|
%p = tail call noalias ptr @calloc(i64 1, i64 4)
|
||||||
store i8 0, i8* %p, align 1
|
store i8 0, ptr %p, align 1
|
||||||
%p.1 = getelementptr i8, i8* %p, i32 1
|
%p.1 = getelementptr i8, ptr %p, i32 1
|
||||||
store i8 0, i8* %p.1, align 1
|
store i8 0, ptr %p.1, align 1
|
||||||
%p.3 = getelementptr i8, i8* %p, i32 3
|
%p.3 = getelementptr i8, ptr %p, i32 3
|
||||||
store i8 5, i8* %p.3, align 1
|
store i8 5, ptr %p.3, align 1
|
||||||
%p.2 = getelementptr i8, i8* %p, i32 2
|
%p.2 = getelementptr i8, ptr %p, i32 2
|
||||||
store i8 0, i8* %p.2, align 1
|
store i8 0, ptr %p.2, align 1
|
||||||
ret i8* %p
|
ret ptr %p
|
||||||
}
|
}
|
||||||
|
|
||||||
define i8* @test11() {
|
define ptr @test11() {
|
||||||
; CHECK-LABEL: @test11(
|
; CHECK-LABEL: @test11(
|
||||||
; CHECK-NEXT: [[P:%.*]] = tail call noalias i8* @calloc(i64 1, i64 4)
|
; CHECK-NEXT: [[P:%.*]] = tail call noalias ptr @calloc(i64 1, i64 4)
|
||||||
; CHECK-NEXT: ret i8* [[P]]
|
; CHECK-NEXT: ret ptr [[P]]
|
||||||
;
|
;
|
||||||
|
|
||||||
%p = tail call noalias i8* @calloc(i64 1, i64 4)
|
%p = tail call noalias ptr @calloc(i64 1, i64 4)
|
||||||
store i8 0, i8* %p, align 1
|
store i8 0, ptr %p, align 1
|
||||||
%p.1 = getelementptr i8, i8* %p, i32 1
|
%p.1 = getelementptr i8, ptr %p, i32 1
|
||||||
store i8 0, i8* %p.1, align 1
|
store i8 0, ptr %p.1, align 1
|
||||||
%p.3 = getelementptr i8, i8* %p, i32 3
|
%p.3 = getelementptr i8, ptr %p, i32 3
|
||||||
store i8 5, i8* %p.3, align 1
|
store i8 5, ptr %p.3, align 1
|
||||||
%p.2 = getelementptr i8, i8* %p, i32 2
|
%p.2 = getelementptr i8, ptr %p, i32 2
|
||||||
store i8 0, i8* %p.2, align 1
|
store i8 0, ptr %p.2, align 1
|
||||||
%p.3.2 = getelementptr i8, i8* %p, i32 3
|
%p.3.2 = getelementptr i8, ptr %p, i32 3
|
||||||
store i8 0, i8* %p.3.2, align 1
|
store i8 0, ptr %p.3.2, align 1
|
||||||
ret i8* %p
|
ret ptr %p
|
||||||
}
|
}
|
||||||
|
|
||||||
define i8* @test12() {
|
define ptr @test12() {
|
||||||
; CHECK-LABEL: @test12(
|
; CHECK-LABEL: @test12(
|
||||||
; CHECK-NEXT: [[P:%.*]] = tail call noalias i8* @calloc(i64 1, i64 4)
|
; CHECK-NEXT: [[P:%.*]] = tail call noalias ptr @calloc(i64 1, i64 4)
|
||||||
; CHECK-NEXT: [[P_3:%.*]] = getelementptr i8, i8* [[P]], i32 3
|
; CHECK-NEXT: [[P_3:%.*]] = getelementptr i8, ptr [[P]], i32 3
|
||||||
; CHECK-NEXT: store i8 5, i8* [[P_3]], align 1
|
; CHECK-NEXT: store i8 5, ptr [[P_3]], align 1
|
||||||
; CHECK-NEXT: call void @use(i8* [[P]])
|
; CHECK-NEXT: call void @use(ptr [[P]])
|
||||||
; CHECK-NEXT: [[P_3_2:%.*]] = getelementptr i8, i8* [[P]], i32 3
|
; CHECK-NEXT: [[P_3_2:%.*]] = getelementptr i8, ptr [[P]], i32 3
|
||||||
; CHECK-NEXT: store i8 0, i8* [[P_3_2]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[P_3_2]], align 1
|
||||||
; CHECK-NEXT: ret i8* [[P]]
|
; CHECK-NEXT: ret ptr [[P]]
|
||||||
;
|
;
|
||||||
|
|
||||||
%p = tail call noalias i8* @calloc(i64 1, i64 4)
|
%p = tail call noalias ptr @calloc(i64 1, i64 4)
|
||||||
%p.3 = getelementptr i8, i8* %p, i32 3
|
%p.3 = getelementptr i8, ptr %p, i32 3
|
||||||
store i8 5, i8* %p.3, align 1
|
store i8 5, ptr %p.3, align 1
|
||||||
call void @use(i8* %p)
|
call void @use(ptr %p)
|
||||||
%p.3.2 = getelementptr i8, i8* %p, i32 3
|
%p.3.2 = getelementptr i8, ptr %p, i32 3
|
||||||
store i8 0, i8* %p.3.2, align 1
|
store i8 0, ptr %p.3.2, align 1
|
||||||
ret i8* %p
|
ret ptr %p
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @use(i8*) readonly
|
declare void @use(ptr) readonly
|
||||||
|
|
|
@ -9,52 +9,52 @@ define i32 @other_value_escapes_before_call() {
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[V1:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[V1:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[V2:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[V2:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: store i32 0, i32* [[V1]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[V1]], align 4
|
||||||
; CHECK-NEXT: call void @escape(i32* nonnull [[V1]])
|
; CHECK-NEXT: call void @escape(ptr nonnull [[V1]])
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: store i32 [[CALL]], i32* [[V2]], align 4
|
; CHECK-NEXT: store i32 [[CALL]], ptr [[V2]], align 4
|
||||||
; CHECK-NEXT: call void @escape(i32* nonnull [[V2]])
|
; CHECK-NEXT: call void @escape(ptr nonnull [[V2]])
|
||||||
; CHECK-NEXT: [[LOAD_V2:%.*]] = load i32, i32* [[V2]], align 4
|
; CHECK-NEXT: [[LOAD_V2:%.*]] = load i32, ptr [[V2]], align 4
|
||||||
; CHECK-NEXT: [[LOAD_V1:%.*]] = load i32, i32* [[V1]], align 4
|
; CHECK-NEXT: [[LOAD_V1:%.*]] = load i32, ptr [[V1]], align 4
|
||||||
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[LOAD_V2]], [[LOAD_V1]]
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[LOAD_V2]], [[LOAD_V1]]
|
||||||
; CHECK-NEXT: ret i32 [[ADD]]
|
; CHECK-NEXT: ret i32 [[ADD]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%v1 = alloca i32, align 4
|
%v1 = alloca i32, align 4
|
||||||
%v2 = alloca i32, align 4
|
%v2 = alloca i32, align 4
|
||||||
store i32 0, i32* %v1, align 4
|
store i32 0, ptr %v1, align 4
|
||||||
call void @escape(i32* nonnull %v1)
|
call void @escape(ptr nonnull %v1)
|
||||||
store i32 55555, i32* %v2, align 4
|
store i32 55555, ptr %v2, align 4
|
||||||
%call = call i32 @getval()
|
%call = call i32 @getval()
|
||||||
store i32 %call, i32* %v2, align 4
|
store i32 %call, ptr %v2, align 4
|
||||||
call void @escape(i32* nonnull %v2)
|
call void @escape(ptr nonnull %v2)
|
||||||
%load.v2 = load i32, i32* %v2, align 4
|
%load.v2 = load i32, ptr %v2, align 4
|
||||||
%load.v1 = load i32, i32* %v1, align 4
|
%load.v1 = load i32, ptr %v1, align 4
|
||||||
%add = add nsw i32 %load.v2, %load.v1
|
%add = add nsw i32 %load.v2, %load.v1
|
||||||
ret i32 %add
|
ret i32 %add
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @escape(i32*)
|
declare void @escape(ptr)
|
||||||
|
|
||||||
declare i32 @getval()
|
declare i32 @getval()
|
||||||
|
|
||||||
declare void @escape_and_clobber(i32*)
|
declare void @escape_and_clobber(ptr)
|
||||||
declare void @escape_writeonly(i32*) writeonly
|
declare void @escape_writeonly(ptr) writeonly
|
||||||
declare void @clobber()
|
declare void @clobber()
|
||||||
|
|
||||||
define i32 @test_not_captured_before_call_same_bb() {
|
define i32 @test_not_captured_before_call_same_bb() {
|
||||||
; CHECK-LABEL: @test_not_captured_before_call_same_bb(
|
; CHECK-LABEL: @test_not_captured_before_call_same_bb(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]])
|
; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
|
||||||
; CHECK-NEXT: ret i32 [[R]]
|
; CHECK-NEXT: ret i32 [[R]]
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
%r = call i32 @getval()
|
%r = call i32 @getval()
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
call void @escape_and_clobber(i32* %a)
|
call void @escape_and_clobber(ptr %a)
|
||||||
ret i32 %r
|
ret i32 %r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,40 +62,40 @@ define i32 @test_not_captured_before_call_same_bb_escape_unreachable_block() {
|
||||||
; CHECK-LABEL: @test_not_captured_before_call_same_bb_escape_unreachable_block(
|
; CHECK-LABEL: @test_not_captured_before_call_same_bb_escape_unreachable_block(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]])
|
; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
|
||||||
; CHECK-NEXT: ret i32 [[R]]
|
; CHECK-NEXT: ret i32 [[R]]
|
||||||
; CHECK: unreach:
|
; CHECK: unreach:
|
||||||
; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]])
|
; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
|
||||||
; CHECK-NEXT: ret i32 0
|
; CHECK-NEXT: ret i32 0
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
%r = call i32 @getval()
|
%r = call i32 @getval()
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
call void @escape_and_clobber(i32* %a)
|
call void @escape_and_clobber(ptr %a)
|
||||||
ret i32 %r
|
ret i32 %r
|
||||||
|
|
||||||
unreach:
|
unreach:
|
||||||
call void @escape_and_clobber(i32* %a)
|
call void @escape_and_clobber(ptr %a)
|
||||||
ret i32 0
|
ret i32 0
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test_captured_and_clobbered_after_load_same_bb_2() {
|
define i32 @test_captured_and_clobbered_after_load_same_bb_2() {
|
||||||
; CHECK-LABEL: @test_captured_and_clobbered_after_load_same_bb_2(
|
; CHECK-LABEL: @test_captured_and_clobbered_after_load_same_bb_2(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: store i32 55, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 55, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]])
|
; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: call void @clobber()
|
; CHECK-NEXT: call void @clobber()
|
||||||
; CHECK-NEXT: ret i32 [[R]]
|
; CHECK-NEXT: ret i32 [[R]]
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
%r = call i32 @getval()
|
%r = call i32 @getval()
|
||||||
call void @escape_and_clobber(i32* %a)
|
call void @escape_and_clobber(ptr %a)
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
call void @clobber()
|
call void @clobber()
|
||||||
ret i32 %r
|
ret i32 %r
|
||||||
}
|
}
|
||||||
|
@ -104,16 +104,16 @@ define i32 @test_captured_after_call_same_bb_2_clobbered_later() {
|
||||||
; CHECK-LABEL: @test_captured_after_call_same_bb_2_clobbered_later(
|
; CHECK-LABEL: @test_captured_after_call_same_bb_2_clobbered_later(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
|
; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: call void @clobber()
|
; CHECK-NEXT: call void @clobber()
|
||||||
; CHECK-NEXT: ret i32 [[R]]
|
; CHECK-NEXT: ret i32 [[R]]
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
%r = call i32 @getval()
|
%r = call i32 @getval()
|
||||||
call void @escape_writeonly(i32* %a)
|
call void @escape_writeonly(ptr %a)
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
call void @clobber()
|
call void @clobber()
|
||||||
ret i32 %r
|
ret i32 %r
|
||||||
}
|
}
|
||||||
|
@ -123,23 +123,23 @@ define i32 @test_captured_sibling_path_to_call_other_blocks_1(i1 %c.1) {
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
||||||
; CHECK: then:
|
; CHECK: then:
|
||||||
; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
|
; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
|
||||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||||
; CHECK: else:
|
; CHECK: else:
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: br label [[EXIT]]
|
; CHECK-NEXT: br label [[EXIT]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ELSE]] ]
|
; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ELSE]] ]
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: call void @clobber()
|
; CHECK-NEXT: call void @clobber()
|
||||||
; CHECK-NEXT: ret i32 [[P]]
|
; CHECK-NEXT: ret i32 [[P]]
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
br i1 %c.1, label %then, label %else
|
br i1 %c.1, label %then, label %else
|
||||||
|
|
||||||
then:
|
then:
|
||||||
call void @escape_writeonly(i32* %a)
|
call void @escape_writeonly(ptr %a)
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -148,7 +148,7 @@ else:
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
%p = phi i32 [ 0, %then ], [ %r, %else ]
|
%p = phi i32 [ 0, %then ], [ %r, %else ]
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
call void @clobber()
|
call void @clobber()
|
||||||
ret i32 %p
|
ret i32 %p
|
||||||
}
|
}
|
||||||
|
@ -156,35 +156,35 @@ exit:
|
||||||
define i32 @test_captured_before_call_other_blocks_2(i1 %c.1) {
|
define i32 @test_captured_before_call_other_blocks_2(i1 %c.1) {
|
||||||
; CHECK-LABEL: @test_captured_before_call_other_blocks_2(
|
; CHECK-LABEL: @test_captured_before_call_other_blocks_2(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: store i32 55, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 55, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
||||||
; CHECK: then:
|
; CHECK: then:
|
||||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||||
; CHECK: else:
|
; CHECK: else:
|
||||||
; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]])
|
; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: br label [[EXIT]]
|
; CHECK-NEXT: br label [[EXIT]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ELSE]] ]
|
; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ELSE]] ]
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: call void @clobber()
|
; CHECK-NEXT: call void @clobber()
|
||||||
; CHECK-NEXT: ret i32 [[P]]
|
; CHECK-NEXT: ret i32 [[P]]
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
br i1 %c.1, label %then, label %else
|
br i1 %c.1, label %then, label %else
|
||||||
|
|
||||||
then:
|
then:
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
else:
|
else:
|
||||||
call void @escape_and_clobber(i32* %a)
|
call void @escape_and_clobber(ptr %a)
|
||||||
%r = call i32 @getval()
|
%r = call i32 @getval()
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
%p = phi i32 [ 0, %then ], [ %r, %else ]
|
%p = phi i32 [ 0, %then ], [ %r, %else ]
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
call void @clobber()
|
call void @clobber()
|
||||||
ret i32 %p
|
ret i32 %p
|
||||||
}
|
}
|
||||||
|
@ -193,33 +193,33 @@ define i32 @test_captured_before_call_other_blocks_4(i1 %c.1) {
|
||||||
; CHECK-LABEL: @test_captured_before_call_other_blocks_4(
|
; CHECK-LABEL: @test_captured_before_call_other_blocks_4(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: store i32 55, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 55, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
|
; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
|
||||||
; CHECK: then:
|
; CHECK: then:
|
||||||
; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
|
; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
|
||||||
; CHECK-NEXT: br label [[EXIT]]
|
; CHECK-NEXT: br label [[EXIT]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ENTRY:%.*]] ]
|
; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ENTRY:%.*]] ]
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: call void @clobber()
|
; CHECK-NEXT: call void @clobber()
|
||||||
; CHECK-NEXT: ret i32 [[P]]
|
; CHECK-NEXT: ret i32 [[P]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
call void @escape_writeonly(i32* %a)
|
call void @escape_writeonly(ptr %a)
|
||||||
%r = call i32 @getval()
|
%r = call i32 @getval()
|
||||||
br i1 %c.1, label %then, label %exit
|
br i1 %c.1, label %then, label %exit
|
||||||
|
|
||||||
then:
|
then:
|
||||||
call void @escape_writeonly(i32* %a)
|
call void @escape_writeonly(ptr %a)
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
%p = phi i32 [ 0, %then ], [ %r, %entry ]
|
%p = phi i32 [ 0, %then ], [ %r, %entry ]
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
call void @clobber()
|
call void @clobber()
|
||||||
ret i32 %p
|
ret i32 %p
|
||||||
}
|
}
|
||||||
|
@ -228,29 +228,29 @@ define i32 @test_captured_before_call_other_blocks_5(i1 %c.1) {
|
||||||
; CHECK-LABEL: @test_captured_before_call_other_blocks_5(
|
; CHECK-LABEL: @test_captured_before_call_other_blocks_5(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: store i32 55, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 55, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
|
||||||
; CHECK: then:
|
; CHECK: then:
|
||||||
; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
|
; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
|
||||||
; CHECK-NEXT: br label [[EXIT]]
|
; CHECK-NEXT: br label [[EXIT]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: call void @clobber()
|
; CHECK-NEXT: call void @clobber()
|
||||||
; CHECK-NEXT: ret i32 [[R]]
|
; CHECK-NEXT: ret i32 [[R]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
br i1 %c.1, label %then, label %exit
|
br i1 %c.1, label %then, label %exit
|
||||||
|
|
||||||
then:
|
then:
|
||||||
call void @escape_writeonly(i32* %a)
|
call void @escape_writeonly(ptr %a)
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
%r = call i32 @getval()
|
%r = call i32 @getval()
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
call void @clobber()
|
call void @clobber()
|
||||||
ret i32 %r
|
ret i32 %r
|
||||||
}
|
}
|
||||||
|
@ -259,31 +259,31 @@ define i32 @test_captured_before_call_other_blocks_6(i1 %c.1) {
|
||||||
; CHECK-LABEL: @test_captured_before_call_other_blocks_6(
|
; CHECK-LABEL: @test_captured_before_call_other_blocks_6(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: store i32 55, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 55, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
|
||||||
; CHECK: then:
|
; CHECK: then:
|
||||||
; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
|
; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
|
||||||
; CHECK-NEXT: br label [[EXIT]]
|
; CHECK-NEXT: br label [[EXIT]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
|
; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
|
||||||
; CHECK-NEXT: call void @clobber()
|
; CHECK-NEXT: call void @clobber()
|
||||||
; CHECK-NEXT: ret i32 [[R]]
|
; CHECK-NEXT: ret i32 [[R]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
br i1 %c.1, label %then, label %exit
|
br i1 %c.1, label %then, label %exit
|
||||||
|
|
||||||
then:
|
then:
|
||||||
call void @escape_writeonly(i32* %a)
|
call void @escape_writeonly(ptr %a)
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
%r = call i32 @getval()
|
%r = call i32 @getval()
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
call void @escape_writeonly(i32* %a)
|
call void @escape_writeonly(ptr %a)
|
||||||
call void @clobber()
|
call void @clobber()
|
||||||
ret i32 %r
|
ret i32 %r
|
||||||
}
|
}
|
||||||
|
@ -292,20 +292,20 @@ define i32 @test_not_captured_before_call_other_blocks_1(i1 %c.1) {
|
||||||
; CHECK-LABEL: @test_not_captured_before_call_other_blocks_1(
|
; CHECK-LABEL: @test_not_captured_before_call_other_blocks_1(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
||||||
; CHECK: then:
|
; CHECK: then:
|
||||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||||
; CHECK: else:
|
; CHECK: else:
|
||||||
; CHECK-NEXT: br label [[EXIT]]
|
; CHECK-NEXT: br label [[EXIT]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]])
|
; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
|
||||||
; CHECK-NEXT: ret i32 [[R]]
|
; CHECK-NEXT: ret i32 [[R]]
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
%r = call i32 @getval()
|
%r = call i32 @getval()
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
br i1 %c.1, label %then, label %else
|
br i1 %c.1, label %then, label %else
|
||||||
|
|
||||||
then:
|
then:
|
||||||
|
@ -315,7 +315,7 @@ else:
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
call void @escape_and_clobber(i32* %a)
|
call void @escape_and_clobber(ptr %a)
|
||||||
ret i32 %r
|
ret i32 %r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,29 +323,29 @@ define i32 @test_not_captured_before_call_other_blocks_2(i1 %c.1) {
|
||||||
; CHECK-LABEL: @test_not_captured_before_call_other_blocks_2(
|
; CHECK-LABEL: @test_not_captured_before_call_other_blocks_2(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
||||||
; CHECK: then:
|
; CHECK: then:
|
||||||
; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]])
|
; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
|
||||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||||
; CHECK: else:
|
; CHECK: else:
|
||||||
; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]])
|
; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
|
||||||
; CHECK-NEXT: br label [[EXIT]]
|
; CHECK-NEXT: br label [[EXIT]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: ret i32 [[R]]
|
; CHECK-NEXT: ret i32 [[R]]
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
%r = call i32 @getval()
|
%r = call i32 @getval()
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
br i1 %c.1, label %then, label %else
|
br i1 %c.1, label %then, label %else
|
||||||
|
|
||||||
then:
|
then:
|
||||||
call void @escape_and_clobber(i32* %a)
|
call void @escape_and_clobber(ptr %a)
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
else:
|
else:
|
||||||
call void @escape_and_clobber(i32* %a)
|
call void @escape_and_clobber(ptr %a)
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
@ -356,10 +356,10 @@ define i32 @test_not_captured_before_call_other_blocks_3(i1 %c.1) {
|
||||||
; CHECK-LABEL: @test_not_captured_before_call_other_blocks_3(
|
; CHECK-LABEL: @test_not_captured_before_call_other_blocks_3(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
||||||
; CHECK: then:
|
; CHECK: then:
|
||||||
; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]])
|
; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
|
||||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||||
; CHECK: else:
|
; CHECK: else:
|
||||||
; CHECK-NEXT: br label [[EXIT]]
|
; CHECK-NEXT: br label [[EXIT]]
|
||||||
|
@ -367,13 +367,13 @@ define i32 @test_not_captured_before_call_other_blocks_3(i1 %c.1) {
|
||||||
; CHECK-NEXT: ret i32 [[R]]
|
; CHECK-NEXT: ret i32 [[R]]
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
%r = call i32 @getval()
|
%r = call i32 @getval()
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
br i1 %c.1, label %then, label %else
|
br i1 %c.1, label %then, label %else
|
||||||
|
|
||||||
then:
|
then:
|
||||||
call void @escape_and_clobber(i32* %a)
|
call void @escape_and_clobber(ptr %a)
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -391,16 +391,16 @@ define i32 @test_not_captured_before_call_other_blocks_4(i1 %c.1) {
|
||||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||||
; CHECK: else:
|
; CHECK: else:
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
|
; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
|
||||||
; CHECK-NEXT: br label [[EXIT]]
|
; CHECK-NEXT: br label [[EXIT]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ELSE]] ]
|
; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ELSE]] ]
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: call void @clobber()
|
; CHECK-NEXT: call void @clobber()
|
||||||
; CHECK-NEXT: ret i32 [[P]]
|
; CHECK-NEXT: ret i32 [[P]]
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
br i1 %c.1, label %then, label %else
|
br i1 %c.1, label %then, label %else
|
||||||
|
|
||||||
then:
|
then:
|
||||||
|
@ -408,12 +408,12 @@ then:
|
||||||
|
|
||||||
else:
|
else:
|
||||||
%r = call i32 @getval()
|
%r = call i32 @getval()
|
||||||
call void @escape_writeonly(i32* %a)
|
call void @escape_writeonly(ptr %a)
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
%p = phi i32 [ 0, %then ], [ %r, %else ]
|
%p = phi i32 [ 0, %then ], [ %r, %else ]
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
call void @clobber()
|
call void @clobber()
|
||||||
ret i32 %p
|
ret i32 %p
|
||||||
}
|
}
|
||||||
|
@ -425,27 +425,27 @@ define i32 @test_not_captured_before_call_other_blocks_5(i1 %c.1) {
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
|
||||||
; CHECK: then:
|
; CHECK: then:
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
|
; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
|
||||||
; CHECK-NEXT: br label [[EXIT]]
|
; CHECK-NEXT: br label [[EXIT]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[R]], [[THEN]] ], [ 0, [[ENTRY:%.*]] ]
|
; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[R]], [[THEN]] ], [ 0, [[ENTRY:%.*]] ]
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: call void @clobber()
|
; CHECK-NEXT: call void @clobber()
|
||||||
; CHECK-NEXT: ret i32 [[P]]
|
; CHECK-NEXT: ret i32 [[P]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
br i1 %c.1, label %then, label %exit
|
br i1 %c.1, label %then, label %exit
|
||||||
|
|
||||||
then:
|
then:
|
||||||
%r = call i32 @getval()
|
%r = call i32 @getval()
|
||||||
call void @escape_writeonly(i32* %a)
|
call void @escape_writeonly(ptr %a)
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
%p = phi i32 [ %r, %then ], [ 0, %entry ]
|
%p = phi i32 [ %r, %then ], [ 0, %entry ]
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
call void @clobber()
|
call void @clobber()
|
||||||
ret i32 %p
|
ret i32 %p
|
||||||
}
|
}
|
||||||
|
@ -454,33 +454,33 @@ define i32 @test_not_captured_before_call_other_blocks_6(i1 %c.1) {
|
||||||
; CHECK-LABEL: @test_not_captured_before_call_other_blocks_6(
|
; CHECK-LABEL: @test_not_captured_before_call_other_blocks_6(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: store i32 55, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 55, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
|
||||||
; CHECK: then:
|
; CHECK: then:
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
|
; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
|
||||||
; CHECK-NEXT: br label [[EXIT]]
|
; CHECK-NEXT: br label [[EXIT]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[R]], [[THEN]] ], [ 0, [[ENTRY:%.*]] ]
|
; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[R]], [[THEN]] ], [ 0, [[ENTRY:%.*]] ]
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
|
; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
|
||||||
; CHECK-NEXT: call void @clobber()
|
; CHECK-NEXT: call void @clobber()
|
||||||
; CHECK-NEXT: ret i32 [[P]]
|
; CHECK-NEXT: ret i32 [[P]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
br i1 %c.1, label %then, label %exit
|
br i1 %c.1, label %then, label %exit
|
||||||
|
|
||||||
then:
|
then:
|
||||||
%r = call i32 @getval()
|
%r = call i32 @getval()
|
||||||
call void @escape_writeonly(i32* %a)
|
call void @escape_writeonly(ptr %a)
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
%p = phi i32 [ %r, %then ], [ 0, %entry ]
|
%p = phi i32 [ %r, %then ], [ 0, %entry ]
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
call void @escape_writeonly(i32* %a)
|
call void @escape_writeonly(ptr %a)
|
||||||
call void @clobber()
|
call void @clobber()
|
||||||
ret i32 %p
|
ret i32 %p
|
||||||
}
|
}
|
||||||
|
@ -490,31 +490,31 @@ define i32 @test_not_captured_before_call_other_blocks_7(i1 %c.1) {
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
|
; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
|
||||||
; CHECK: then:
|
; CHECK: then:
|
||||||
; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
|
; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
|
||||||
; CHECK-NEXT: br label [[EXIT]]
|
; CHECK-NEXT: br label [[EXIT]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ENTRY:%.*]] ]
|
; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ENTRY:%.*]] ]
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: call void @clobber()
|
; CHECK-NEXT: call void @clobber()
|
||||||
; CHECK-NEXT: ret i32 [[P]]
|
; CHECK-NEXT: ret i32 [[P]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
%r = call i32 @getval()
|
%r = call i32 @getval()
|
||||||
call void @escape_writeonly(i32* %a)
|
call void @escape_writeonly(ptr %a)
|
||||||
br i1 %c.1, label %then, label %exit
|
br i1 %c.1, label %then, label %exit
|
||||||
|
|
||||||
then:
|
then:
|
||||||
call void @escape_writeonly(i32* %a)
|
call void @escape_writeonly(ptr %a)
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
%p = phi i32 [ 0, %then ], [ %r, %entry ]
|
%p = phi i32 [ 0, %then ], [ %r, %entry ]
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
call void @clobber()
|
call void @clobber()
|
||||||
ret i32 %p
|
ret i32 %p
|
||||||
}
|
}
|
||||||
|
@ -522,20 +522,20 @@ exit:
|
||||||
define i32 @test_not_captured_before_call_same_bb_but_read() {
|
define i32 @test_not_captured_before_call_same_bb_but_read() {
|
||||||
; CHECK-LABEL: @test_not_captured_before_call_same_bb_but_read(
|
; CHECK-LABEL: @test_not_captured_before_call_same_bb_but_read(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: store i32 55, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 55, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[A]], align 4
|
; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]])
|
; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
|
||||||
; CHECK-NEXT: [[RES:%.*]] = add i32 [[R]], [[LV]]
|
; CHECK-NEXT: [[RES:%.*]] = add i32 [[R]], [[LV]]
|
||||||
; CHECK-NEXT: ret i32 [[RES]]
|
; CHECK-NEXT: ret i32 [[RES]]
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
%r = call i32 @getval()
|
%r = call i32 @getval()
|
||||||
%lv = load i32, i32* %a
|
%lv = load i32, ptr %a
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
call void @escape_and_clobber(i32* %a)
|
call void @escape_and_clobber(ptr %a)
|
||||||
%res = add i32 %r, %lv
|
%res = add i32 %r, %lv
|
||||||
ret i32 %res
|
ret i32 %res
|
||||||
}
|
}
|
||||||
|
@ -546,123 +546,121 @@ define i32 @test_captured_after_loop(i1 %c.1) {
|
||||||
; CHECK-NEXT: br label [[LOOP:%.*]]
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||||||
; CHECK: loop:
|
; CHECK: loop:
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[LOOP]], label [[EXIT:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[LOOP]], label [[EXIT:%.*]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]])
|
; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
|
||||||
; CHECK-NEXT: ret i32 [[R]]
|
; CHECK-NEXT: ret i32 [[R]]
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
br label %loop
|
br label %loop
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
%r = call i32 @getval()
|
%r = call i32 @getval()
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
br i1 %c.1, label %loop, label %exit
|
br i1 %c.1, label %loop, label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
call void @escape_and_clobber(i32* %a)
|
call void @escape_and_clobber(ptr %a)
|
||||||
ret i32 %r
|
ret i32 %r
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test_captured_in_loop(i1 %c.1) {
|
define i32 @test_captured_in_loop(i1 %c.1) {
|
||||||
; CHECK-LABEL: @test_captured_in_loop(
|
; CHECK-LABEL: @test_captured_in_loop(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: store i32 55, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 55, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: br label [[LOOP:%.*]]
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||||||
; CHECK: loop:
|
; CHECK: loop:
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval()
|
||||||
; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
|
; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[LOOP]], label [[EXIT:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[LOOP]], label [[EXIT:%.*]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]])
|
; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
|
||||||
; CHECK-NEXT: ret i32 [[R]]
|
; CHECK-NEXT: ret i32 [[R]]
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
br label %loop
|
br label %loop
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
%r = call i32 @getval()
|
%r = call i32 @getval()
|
||||||
call void @escape_writeonly(i32* %a)
|
call void @escape_writeonly(ptr %a)
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
br i1 %c.1, label %loop, label %exit
|
br i1 %c.1, label %loop, label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
call void @escape_and_clobber(i32* %a)
|
call void @escape_and_clobber(ptr %a)
|
||||||
ret i32 %r
|
ret i32 %r
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1)
|
declare void @llvm.memcpy.p0.p0.i64(ptr, ptr, i64, i1)
|
||||||
define void @test_escaping_store_removed(i8* %src, i64** %escape) {
|
define void @test_escaping_store_removed(ptr %src, ptr %escape) {
|
||||||
; CHECK-LABEL: @test_escaping_store_removed(
|
; CHECK-LABEL: @test_escaping_store_removed(
|
||||||
; CHECK-NEXT: bb:
|
; CHECK-NEXT: bb:
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i64, align 8
|
; CHECK-NEXT: [[A:%.*]] = alloca i64, align 8
|
||||||
; CHECK-NEXT: [[EXT_A:%.*]] = bitcast i64* [[A]] to i8*
|
|
||||||
; CHECK-NEXT: call void @clobber()
|
; CHECK-NEXT: call void @clobber()
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[EXT_A]], i8* [[SRC:%.*]], i64 8, i1 false)
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[A]], ptr [[SRC:%.*]], i64 8, i1 false)
|
||||||
; CHECK-NEXT: store i64* [[A]], i64** [[ESCAPE:%.*]], align 8
|
; CHECK-NEXT: store ptr [[A]], ptr [[ESCAPE:%.*]], align 8
|
||||||
; CHECK-NEXT: call void @clobber()
|
; CHECK-NEXT: call void @clobber()
|
||||||
; CHECK-NEXT: store i64 99, i64* [[A]], align 8
|
; CHECK-NEXT: store i64 99, ptr [[A]], align 8
|
||||||
; CHECK-NEXT: call void @clobber()
|
; CHECK-NEXT: call void @clobber()
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
bb:
|
bb:
|
||||||
%a = alloca i64, align 8
|
%a = alloca i64, align 8
|
||||||
%ext.a = bitcast i64* %a to i8*
|
store i64 0, ptr %a
|
||||||
store i64 0, i64* %a
|
|
||||||
call void @clobber()
|
call void @clobber()
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %ext.a, i8* %src, i64 8, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %a, ptr %src, i64 8, i1 false)
|
||||||
store i64* %a, i64** %escape, align 8
|
store ptr %a, ptr %escape, align 8
|
||||||
store i64* %a, i64** %escape, align 8
|
store ptr %a, ptr %escape, align 8
|
||||||
call void @clobber()
|
call void @clobber()
|
||||||
store i64 99, i64* %a
|
store i64 99, ptr %a
|
||||||
call void @clobber()
|
call void @clobber()
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
define void @test_invoke_captures() personality i8* undef {
|
define void @test_invoke_captures() personality ptr undef {
|
||||||
; CHECK-LABEL: @test_invoke_captures(
|
; CHECK-LABEL: @test_invoke_captures(
|
||||||
; CHECK-NEXT: bb:
|
; CHECK-NEXT: bb:
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: invoke void @clobber()
|
; CHECK-NEXT: invoke void @clobber()
|
||||||
; CHECK-NEXT: to label [[BB2:%.*]] unwind label [[BB5:%.*]]
|
; CHECK-NEXT: to label [[BB2:%.*]] unwind label [[BB5:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[A]], align 8
|
; CHECK-NEXT: store i32 0, ptr [[A]], align 8
|
||||||
; CHECK-NEXT: invoke void @escape(i32* [[A]])
|
; CHECK-NEXT: invoke void @escape(ptr [[A]])
|
||||||
; CHECK-NEXT: to label [[BB9:%.*]] unwind label [[BB10:%.*]]
|
; CHECK-NEXT: to label [[BB9:%.*]] unwind label [[BB10:%.*]]
|
||||||
; CHECK: bb4:
|
; CHECK: bb4:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb5:
|
; CHECK: bb5:
|
||||||
; CHECK-NEXT: [[LP_1:%.*]] = landingpad { i8*, i32 }
|
; CHECK-NEXT: [[LP_1:%.*]] = landingpad { ptr, i32 }
|
||||||
; CHECK-NEXT: cleanup
|
; CHECK-NEXT: cleanup
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb9:
|
; CHECK: bb9:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb10:
|
; CHECK: bb10:
|
||||||
; CHECK-NEXT: [[LP_2:%.*]] = landingpad { i8*, i32 }
|
; CHECK-NEXT: [[LP_2:%.*]] = landingpad { ptr, i32 }
|
||||||
; CHECK-NEXT: cleanup
|
; CHECK-NEXT: cleanup
|
||||||
; CHECK-NEXT: unreachable
|
; CHECK-NEXT: unreachable
|
||||||
;
|
;
|
||||||
bb:
|
bb:
|
||||||
%a = alloca i32
|
%a = alloca i32
|
||||||
store i32 99, i32* %a
|
store i32 99, ptr %a
|
||||||
invoke void @clobber()
|
invoke void @clobber()
|
||||||
to label %bb2 unwind label %bb5
|
to label %bb2 unwind label %bb5
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
store i32 0, i32* %a, align 8
|
store i32 0, ptr %a, align 8
|
||||||
invoke void @escape(i32* %a)
|
invoke void @escape(ptr %a)
|
||||||
to label %bb9 unwind label %bb10
|
to label %bb9 unwind label %bb10
|
||||||
|
|
||||||
bb4:
|
bb4:
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
bb5:
|
bb5:
|
||||||
%lp.1 = landingpad { i8*, i32 }
|
%lp.1 = landingpad { ptr, i32 }
|
||||||
cleanup
|
cleanup
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
|
@ -670,40 +668,40 @@ bb9:
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
bb10:
|
bb10:
|
||||||
%lp.2 = landingpad { i8*, i32 }
|
%lp.2 = landingpad { ptr, i32 }
|
||||||
cleanup
|
cleanup
|
||||||
unreachable
|
unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
declare noalias i32* @alloc() nounwind
|
declare noalias ptr @alloc() nounwind
|
||||||
declare i32 @getval_nounwind() nounwind
|
declare i32 @getval_nounwind() nounwind
|
||||||
|
|
||||||
define i32 @test_not_captured_before_load_same_bb_noalias_call() {
|
define i32 @test_not_captured_before_load_same_bb_noalias_call() {
|
||||||
; CHECK-LABEL: @test_not_captured_before_load_same_bb_noalias_call(
|
; CHECK-LABEL: @test_not_captured_before_load_same_bb_noalias_call(
|
||||||
; CHECK-NEXT: [[A:%.*]] = call i32* @alloc()
|
; CHECK-NEXT: [[A:%.*]] = call ptr @alloc()
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval_nounwind()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval_nounwind()
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]])
|
; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
|
||||||
; CHECK-NEXT: ret i32 [[R]]
|
; CHECK-NEXT: ret i32 [[R]]
|
||||||
;
|
;
|
||||||
%a = call i32* @alloc()
|
%a = call ptr @alloc()
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
%r = call i32 @getval_nounwind()
|
%r = call i32 @getval_nounwind()
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
call void @escape_and_clobber(i32* %a)
|
call void @escape_and_clobber(ptr %a)
|
||||||
ret i32 %r
|
ret i32 %r
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test_not_captured_before_load_same_bb_noalias_arg(i32* noalias %a) {
|
define i32 @test_not_captured_before_load_same_bb_noalias_arg(ptr noalias %a) {
|
||||||
; CHECK-LABEL: @test_not_captured_before_load_same_bb_noalias_arg(
|
; CHECK-LABEL: @test_not_captured_before_load_same_bb_noalias_arg(
|
||||||
; CHECK-NEXT: [[R:%.*]] = call i32 @getval_nounwind()
|
; CHECK-NEXT: [[R:%.*]] = call i32 @getval_nounwind()
|
||||||
; CHECK-NEXT: store i32 99, i32* [[A:%.*]], align 4
|
; CHECK-NEXT: store i32 99, ptr [[A:%.*]], align 4
|
||||||
; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]])
|
; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
|
||||||
; CHECK-NEXT: ret i32 [[R]]
|
; CHECK-NEXT: ret i32 [[R]]
|
||||||
;
|
;
|
||||||
store i32 55, i32* %a
|
store i32 55, ptr %a
|
||||||
%r = call i32 @getval_nounwind()
|
%r = call i32 @getval_nounwind()
|
||||||
store i32 99, i32* %a, align 4
|
store i32 99, ptr %a, align 4
|
||||||
call void @escape_and_clobber(i32* %a)
|
call void @escape_and_clobber(ptr %a)
|
||||||
ret i32 %r
|
ret i32 %r
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,23 +5,21 @@ target triple = "powerpc64le-unknown-linux"
|
||||||
|
|
||||||
%"struct.std::complex" = type { { float, float } }
|
%"struct.std::complex" = type { { float, float } }
|
||||||
|
|
||||||
define void @_Z4testSt7complexIfE(%"struct.std::complex"* noalias nocapture sret(%"struct.std::complex") %agg.result, i64 %c.coerce) {
|
define void @_Z4testSt7complexIfE(ptr noalias nocapture sret(%"struct.std::complex") %agg.result, i64 %c.coerce) {
|
||||||
; CHECK-LABEL: @_Z4testSt7complexIfE(
|
; CHECK-LABEL: @_Z4testSt7complexIfE(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[REF_TMP:%.*]] = alloca i64, align 8
|
; CHECK-NEXT: [[REF_TMP:%.*]] = alloca i64, align 8
|
||||||
; CHECK-NEXT: [[TMPCAST:%.*]] = bitcast i64* [[REF_TMP]] to %"struct.std::complex"*
|
|
||||||
; CHECK-NEXT: [[C_SROA_0_0_EXTRACT_SHIFT:%.*]] = lshr i64 [[C_COERCE:%.*]], 32
|
; CHECK-NEXT: [[C_SROA_0_0_EXTRACT_SHIFT:%.*]] = lshr i64 [[C_COERCE:%.*]], 32
|
||||||
; CHECK-NEXT: [[C_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[C_SROA_0_0_EXTRACT_SHIFT]] to i32
|
; CHECK-NEXT: [[C_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[C_SROA_0_0_EXTRACT_SHIFT]] to i32
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32 [[C_SROA_0_0_EXTRACT_TRUNC]] to float
|
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32 [[C_SROA_0_0_EXTRACT_TRUNC]] to float
|
||||||
; CHECK-NEXT: [[C_SROA_2_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[C_COERCE]] to i32
|
; CHECK-NEXT: [[C_SROA_2_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[C_COERCE]] to i32
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 [[C_SROA_2_0_EXTRACT_TRUNC]] to float
|
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 [[C_SROA_2_0_EXTRACT_TRUNC]] to float
|
||||||
; CHECK-NEXT: call void @_Z3barSt7complexIfE(%"struct.std::complex"* nonnull sret(%"struct.std::complex") [[TMPCAST]], i64 [[C_COERCE]])
|
; CHECK-NEXT: call void @_Z3barSt7complexIfE(ptr nonnull sret(%"struct.std::complex") [[REF_TMP]], i64 [[C_COERCE]])
|
||||||
; CHECK-NEXT: [[TMP2:%.*]] = load i64, i64* [[REF_TMP]], align 8
|
; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[REF_TMP]], align 8
|
||||||
; CHECK-NEXT: [[_M_VALUE_REALP_I_I:%.*]] = getelementptr inbounds %"struct.std::complex", %"struct.std::complex"* [[AGG_RESULT:%.*]], i64 0, i32 0, i32 0
|
|
||||||
; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[TMP2]], 32
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[TMP2]], 32
|
||||||
; CHECK-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32
|
||||||
; CHECK-NEXT: [[TMP5:%.*]] = bitcast i32 [[TMP4]] to float
|
; CHECK-NEXT: [[TMP5:%.*]] = bitcast i32 [[TMP4]] to float
|
||||||
; CHECK-NEXT: [[_M_VALUE_IMAGP_I_I:%.*]] = getelementptr inbounds %"struct.std::complex", %"struct.std::complex"* [[AGG_RESULT]], i64 0, i32 0, i32 1
|
; CHECK-NEXT: [[_M_VALUE_IMAGP_I_I:%.*]] = getelementptr inbounds %"struct.std::complex", ptr [[AGG_RESULT:%.*]], i64 0, i32 0, i32 1
|
||||||
; CHECK-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP2]] to i32
|
; CHECK-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP2]] to i32
|
||||||
; CHECK-NEXT: [[TMP7:%.*]] = bitcast i32 [[TMP6]] to float
|
; CHECK-NEXT: [[TMP7:%.*]] = bitcast i32 [[TMP6]] to float
|
||||||
; CHECK-NEXT: [[MUL_AD_I_I:%.*]] = fmul fast float [[TMP5]], [[TMP1]]
|
; CHECK-NEXT: [[MUL_AD_I_I:%.*]] = fmul fast float [[TMP5]], [[TMP1]]
|
||||||
|
@ -30,117 +28,96 @@ define void @_Z4testSt7complexIfE(%"struct.std::complex"* noalias nocapture sret
|
||||||
; CHECK-NEXT: [[MUL_AC_I_I:%.*]] = fmul fast float [[TMP5]], [[TMP0]]
|
; CHECK-NEXT: [[MUL_AC_I_I:%.*]] = fmul fast float [[TMP5]], [[TMP0]]
|
||||||
; CHECK-NEXT: [[MUL_BD_I_I:%.*]] = fmul fast float [[TMP7]], [[TMP1]]
|
; CHECK-NEXT: [[MUL_BD_I_I:%.*]] = fmul fast float [[TMP7]], [[TMP1]]
|
||||||
; CHECK-NEXT: [[MUL_R_I_I:%.*]] = fsub fast float [[MUL_AC_I_I]], [[MUL_BD_I_I]]
|
; CHECK-NEXT: [[MUL_R_I_I:%.*]] = fsub fast float [[MUL_AC_I_I]], [[MUL_BD_I_I]]
|
||||||
; CHECK-NEXT: store float [[MUL_R_I_I]], float* [[_M_VALUE_REALP_I_I]], align 4
|
; CHECK-NEXT: store float [[MUL_R_I_I]], ptr [[AGG_RESULT]], align 4
|
||||||
; CHECK-NEXT: store float [[MUL_I_I_I]], float* [[_M_VALUE_IMAGP_I_I]], align 4
|
; CHECK-NEXT: store float [[MUL_I_I_I]], ptr [[_M_VALUE_IMAGP_I_I]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
%ref.tmp = alloca i64, align 8
|
%ref.tmp = alloca i64, align 8
|
||||||
%tmpcast = bitcast i64* %ref.tmp to %"struct.std::complex"*
|
|
||||||
%c.sroa.0.0.extract.shift = lshr i64 %c.coerce, 32
|
%c.sroa.0.0.extract.shift = lshr i64 %c.coerce, 32
|
||||||
%c.sroa.0.0.extract.trunc = trunc i64 %c.sroa.0.0.extract.shift to i32
|
%c.sroa.0.0.extract.trunc = trunc i64 %c.sroa.0.0.extract.shift to i32
|
||||||
%0 = bitcast i32 %c.sroa.0.0.extract.trunc to float
|
%0 = bitcast i32 %c.sroa.0.0.extract.trunc to float
|
||||||
%c.sroa.2.0.extract.trunc = trunc i64 %c.coerce to i32
|
%c.sroa.2.0.extract.trunc = trunc i64 %c.coerce to i32
|
||||||
%1 = bitcast i32 %c.sroa.2.0.extract.trunc to float
|
%1 = bitcast i32 %c.sroa.2.0.extract.trunc to float
|
||||||
call void @_Z3barSt7complexIfE(%"struct.std::complex"* nonnull sret(%"struct.std::complex") %tmpcast, i64 %c.coerce)
|
call void @_Z3barSt7complexIfE(ptr nonnull sret(%"struct.std::complex") %ref.tmp, i64 %c.coerce)
|
||||||
%2 = bitcast %"struct.std::complex"* %agg.result to i64*
|
%2 = load i64, ptr %ref.tmp, align 8
|
||||||
%3 = load i64, i64* %ref.tmp, align 8
|
store i64 %2, ptr %agg.result, align 4
|
||||||
store i64 %3, i64* %2, align 4
|
|
||||||
|
|
||||||
%_M_value.realp.i.i = getelementptr inbounds %"struct.std::complex", %"struct.std::complex"* %agg.result, i64 0, i32 0, i32 0
|
%3 = lshr i64 %2, 32
|
||||||
%4 = lshr i64 %3, 32
|
%4 = trunc i64 %3 to i32
|
||||||
%5 = trunc i64 %4 to i32
|
%5 = bitcast i32 %4 to float
|
||||||
%6 = bitcast i32 %5 to float
|
%_M_value.imagp.i.i = getelementptr inbounds %"struct.std::complex", ptr %agg.result, i64 0, i32 0, i32 1
|
||||||
%_M_value.imagp.i.i = getelementptr inbounds %"struct.std::complex", %"struct.std::complex"* %agg.result, i64 0, i32 0, i32 1
|
%6 = trunc i64 %2 to i32
|
||||||
%7 = trunc i64 %3 to i32
|
%7 = bitcast i32 %6 to float
|
||||||
%8 = bitcast i32 %7 to float
|
%mul_ad.i.i = fmul fast float %5, %1
|
||||||
%mul_ad.i.i = fmul fast float %6, %1
|
%mul_bc.i.i = fmul fast float %7, %0
|
||||||
%mul_bc.i.i = fmul fast float %8, %0
|
|
||||||
%mul_i.i.i = fadd fast float %mul_ad.i.i, %mul_bc.i.i
|
%mul_i.i.i = fadd fast float %mul_ad.i.i, %mul_bc.i.i
|
||||||
%mul_ac.i.i = fmul fast float %6, %0
|
%mul_ac.i.i = fmul fast float %5, %0
|
||||||
%mul_bd.i.i = fmul fast float %8, %1
|
%mul_bd.i.i = fmul fast float %7, %1
|
||||||
%mul_r.i.i = fsub fast float %mul_ac.i.i, %mul_bd.i.i
|
%mul_r.i.i = fsub fast float %mul_ac.i.i, %mul_bd.i.i
|
||||||
store float %mul_r.i.i, float* %_M_value.realp.i.i, align 4
|
store float %mul_r.i.i, ptr %agg.result, align 4
|
||||||
store float %mul_i.i.i, float* %_M_value.imagp.i.i, align 4
|
store float %mul_i.i.i, ptr %_M_value.imagp.i.i, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @_Z3barSt7complexIfE(%"struct.std::complex"* sret(%"struct.std::complex"), i64)
|
declare void @_Z3barSt7complexIfE(ptr sret(%"struct.std::complex"), i64)
|
||||||
|
|
||||||
define void @test1(i32 *%ptr) {
|
define void @test1(ptr %ptr) {
|
||||||
; CHECK-LABEL: @test1(
|
; CHECK-LABEL: @test1(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[BPTR:%.*]] = bitcast i32* [[PTR:%.*]] to i8*
|
; CHECK-NEXT: store i16 -30062, ptr [[PTR:%.*]], align 2
|
||||||
; CHECK-NEXT: [[WPTR:%.*]] = bitcast i32* [[PTR]] to i16*
|
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 3
|
||||||
; CHECK-NEXT: store i16 -30062, i16* [[WPTR]], align 2
|
; CHECK-NEXT: store i8 47, ptr [[BPTR3]], align 1
|
||||||
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 3
|
; CHECK-NEXT: [[BPTR1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 1
|
||||||
; CHECK-NEXT: store i8 47, i8* [[BPTR3]], align 1
|
; CHECK-NEXT: store i16 2020, ptr [[BPTR1]], align 1
|
||||||
; CHECK-NEXT: [[BPTR1:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 1
|
|
||||||
; CHECK-NEXT: [[WPTRP:%.*]] = bitcast i8* [[BPTR1]] to i16*
|
|
||||||
; CHECK-NEXT: store i16 2020, i16* [[WPTRP]], align 1
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
store i32 5, i32* %ptr
|
store i32 5, ptr %ptr
|
||||||
%bptr = bitcast i32* %ptr to i8*
|
store i8 7, ptr %ptr
|
||||||
store i8 7, i8* %bptr
|
store i16 -30062, ptr %ptr
|
||||||
%wptr = bitcast i32* %ptr to i16*
|
%bptr2 = getelementptr inbounds i8, ptr %ptr, i64 2
|
||||||
store i16 -30062, i16* %wptr
|
store i8 25, ptr %bptr2
|
||||||
%bptr2 = getelementptr inbounds i8, i8* %bptr, i64 2
|
%bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
||||||
store i8 25, i8* %bptr2
|
store i8 47, ptr %bptr3
|
||||||
%bptr3 = getelementptr inbounds i8, i8* %bptr, i64 3
|
%bptr1 = getelementptr inbounds i8, ptr %ptr, i64 1
|
||||||
store i8 47, i8* %bptr3
|
store i16 2020, ptr %bptr1, align 1
|
||||||
%bptr1 = getelementptr inbounds i8, i8* %bptr, i64 1
|
|
||||||
%wptrp = bitcast i8* %bptr1 to i16*
|
|
||||||
store i16 2020, i16* %wptrp, align 1
|
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test2(i32 *%ptr) {
|
define void @test2(ptr %ptr) {
|
||||||
; CHECK-LABEL: @test2(
|
; CHECK-LABEL: @test2(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[BPTR:%.*]] = bitcast i32* [[PTR:%.*]] to i8*
|
; CHECK-NEXT: [[BPTRM1:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 -1
|
||||||
; CHECK-NEXT: [[BPTRM1:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 -1
|
; CHECK-NEXT: [[BPTR1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 1
|
||||||
; CHECK-NEXT: [[BPTR1:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 1
|
; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 2
|
||||||
; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 2
|
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 3
|
||||||
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 3
|
; CHECK-NEXT: store i16 1456, ptr [[BPTRM1]], align 1
|
||||||
; CHECK-NEXT: [[WPTR:%.*]] = bitcast i8* [[BPTR]] to i16*
|
; CHECK-NEXT: store i16 1346, ptr [[PTR]], align 1
|
||||||
; CHECK-NEXT: [[WPTRM1:%.*]] = bitcast i8* [[BPTRM1]] to i16*
|
; CHECK-NEXT: store i16 1756, ptr [[BPTR1]], align 1
|
||||||
; CHECK-NEXT: [[WPTR1:%.*]] = bitcast i8* [[BPTR1]] to i16*
|
; CHECK-NEXT: store i16 1126, ptr [[BPTR2]], align 1
|
||||||
; CHECK-NEXT: [[WPTR2:%.*]] = bitcast i8* [[BPTR2]] to i16*
|
; CHECK-NEXT: store i16 5656, ptr [[BPTR3]], align 1
|
||||||
; CHECK-NEXT: [[WPTR3:%.*]] = bitcast i8* [[BPTR3]] to i16*
|
|
||||||
; CHECK-NEXT: store i16 1456, i16* [[WPTRM1]], align 1
|
|
||||||
; CHECK-NEXT: store i16 1346, i16* [[WPTR]], align 1
|
|
||||||
; CHECK-NEXT: store i16 1756, i16* [[WPTR1]], align 1
|
|
||||||
; CHECK-NEXT: store i16 1126, i16* [[WPTR2]], align 1
|
|
||||||
; CHECK-NEXT: store i16 5656, i16* [[WPTR3]], align 1
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
store i32 5, i32* %ptr
|
store i32 5, ptr %ptr
|
||||||
|
|
||||||
%bptr = bitcast i32* %ptr to i8*
|
%bptrm1 = getelementptr inbounds i8, ptr %ptr, i64 -1
|
||||||
%bptrm1 = getelementptr inbounds i8, i8* %bptr, i64 -1
|
%bptr1 = getelementptr inbounds i8, ptr %ptr, i64 1
|
||||||
%bptr1 = getelementptr inbounds i8, i8* %bptr, i64 1
|
%bptr2 = getelementptr inbounds i8, ptr %ptr, i64 2
|
||||||
%bptr2 = getelementptr inbounds i8, i8* %bptr, i64 2
|
%bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
||||||
%bptr3 = getelementptr inbounds i8, i8* %bptr, i64 3
|
|
||||||
|
|
||||||
%wptr = bitcast i8* %bptr to i16*
|
|
||||||
%wptrm1 = bitcast i8* %bptrm1 to i16*
|
|
||||||
%wptr1 = bitcast i8* %bptr1 to i16*
|
|
||||||
%wptr2 = bitcast i8* %bptr2 to i16*
|
|
||||||
%wptr3 = bitcast i8* %bptr3 to i16*
|
|
||||||
|
|
||||||
store i16 1456, i16* %wptrm1, align 1
|
store i16 1456, ptr %bptrm1, align 1
|
||||||
store i16 1346, i16* %wptr, align 1
|
store i16 1346, ptr %ptr, align 1
|
||||||
store i16 1756, i16* %wptr1, align 1
|
store i16 1756, ptr %bptr1, align 1
|
||||||
store i16 1126, i16* %wptr2, align 1
|
store i16 1126, ptr %bptr2, align 1
|
||||||
store i16 5656, i16* %wptr3, align 1
|
store i16 5656, ptr %bptr3, align 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -148,50 +125,38 @@ entry:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define signext i8 @test3(i32 *%ptr) {
|
define signext i8 @test3(ptr %ptr) {
|
||||||
; CHECK-LABEL: @test3(
|
; CHECK-LABEL: @test3(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i32 5, i32* [[PTR:%.*]], align 4
|
; CHECK-NEXT: store i32 5, ptr [[PTR:%.*]], align 4
|
||||||
; CHECK-NEXT: [[BPTR:%.*]] = bitcast i32* [[PTR]] to i8*
|
; CHECK-NEXT: [[BPTRM1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 -1
|
||||||
; CHECK-NEXT: [[BPTRM1:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 -1
|
; CHECK-NEXT: [[BPTR1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 1
|
||||||
; CHECK-NEXT: [[BPTR1:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 1
|
; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 2
|
||||||
; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 2
|
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 3
|
||||||
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 3
|
; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[PTR]], align 1
|
||||||
; CHECK-NEXT: [[WPTR:%.*]] = bitcast i8* [[BPTR]] to i16*
|
; CHECK-NEXT: store i16 1456, ptr [[BPTRM1]], align 1
|
||||||
; CHECK-NEXT: [[WPTRM1:%.*]] = bitcast i8* [[BPTRM1]] to i16*
|
; CHECK-NEXT: store i16 1346, ptr [[PTR]], align 1
|
||||||
; CHECK-NEXT: [[WPTR1:%.*]] = bitcast i8* [[BPTR1]] to i16*
|
; CHECK-NEXT: store i16 1756, ptr [[BPTR1]], align 1
|
||||||
; CHECK-NEXT: [[WPTR2:%.*]] = bitcast i8* [[BPTR2]] to i16*
|
; CHECK-NEXT: store i16 1126, ptr [[BPTR2]], align 1
|
||||||
; CHECK-NEXT: [[WPTR3:%.*]] = bitcast i8* [[BPTR3]] to i16*
|
; CHECK-NEXT: store i16 5656, ptr [[BPTR3]], align 1
|
||||||
; CHECK-NEXT: [[V:%.*]] = load i8, i8* [[BPTR]], align 1
|
|
||||||
; CHECK-NEXT: store i16 1456, i16* [[WPTRM1]], align 1
|
|
||||||
; CHECK-NEXT: store i16 1346, i16* [[WPTR]], align 1
|
|
||||||
; CHECK-NEXT: store i16 1756, i16* [[WPTR1]], align 1
|
|
||||||
; CHECK-NEXT: store i16 1126, i16* [[WPTR2]], align 1
|
|
||||||
; CHECK-NEXT: store i16 5656, i16* [[WPTR3]], align 1
|
|
||||||
; CHECK-NEXT: ret i8 [[V]]
|
; CHECK-NEXT: ret i8 [[V]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
store i32 5, i32* %ptr
|
store i32 5, ptr %ptr
|
||||||
|
|
||||||
%bptr = bitcast i32* %ptr to i8*
|
%bptrm1 = getelementptr inbounds i8, ptr %ptr, i64 -1
|
||||||
%bptrm1 = getelementptr inbounds i8, i8* %bptr, i64 -1
|
%bptr1 = getelementptr inbounds i8, ptr %ptr, i64 1
|
||||||
%bptr1 = getelementptr inbounds i8, i8* %bptr, i64 1
|
%bptr2 = getelementptr inbounds i8, ptr %ptr, i64 2
|
||||||
%bptr2 = getelementptr inbounds i8, i8* %bptr, i64 2
|
%bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
||||||
%bptr3 = getelementptr inbounds i8, i8* %bptr, i64 3
|
|
||||||
|
|
||||||
%wptr = bitcast i8* %bptr to i16*
|
|
||||||
%wptrm1 = bitcast i8* %bptrm1 to i16*
|
|
||||||
%wptr1 = bitcast i8* %bptr1 to i16*
|
|
||||||
%wptr2 = bitcast i8* %bptr2 to i16*
|
|
||||||
%wptr3 = bitcast i8* %bptr3 to i16*
|
|
||||||
|
|
||||||
%v = load i8, i8* %bptr, align 1
|
%v = load i8, ptr %ptr, align 1
|
||||||
store i16 1456, i16* %wptrm1, align 1
|
store i16 1456, ptr %bptrm1, align 1
|
||||||
store i16 1346, i16* %wptr, align 1
|
store i16 1346, ptr %ptr, align 1
|
||||||
store i16 1756, i16* %wptr1, align 1
|
store i16 1756, ptr %bptr1, align 1
|
||||||
store i16 1126, i16* %wptr2, align 1
|
store i16 1126, ptr %bptr2, align 1
|
||||||
store i16 5656, i16* %wptr3, align 1
|
store i16 5656, ptr %bptr3, align 1
|
||||||
|
|
||||||
|
|
||||||
ret i8 %v
|
ret i8 %v
|
||||||
|
@ -199,15 +164,15 @@ entry:
|
||||||
}
|
}
|
||||||
|
|
||||||
%struct.foostruct = type {
|
%struct.foostruct = type {
|
||||||
i32 (i8*, i8**, i32, i8, i8*)*,
|
ptr,
|
||||||
i32 (i8*, i8**, i32, i8, i8*)*,
|
ptr,
|
||||||
i32 (i8*, i8**, i32, i8, i8*)*,
|
ptr,
|
||||||
i32 (i8*, i8**, i32, i8, i8*)*,
|
ptr,
|
||||||
void (i8*, i32, i32)*
|
ptr
|
||||||
}
|
}
|
||||||
declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1)
|
declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1)
|
||||||
declare void @goFunc(%struct.foostruct*)
|
declare void @goFunc(ptr)
|
||||||
declare i32 @fa(i8*, i8**, i32, i8, i8*)
|
declare i32 @fa(ptr, ptr, i32, i8, ptr)
|
||||||
|
|
||||||
; We miss this case, because of an aggressive limit of partial overlap analysis.
|
; We miss this case, because of an aggressive limit of partial overlap analysis.
|
||||||
; With a larger partial store limit, we remove the memset.
|
; With a larger partial store limit, we remove the memset.
|
||||||
|
@ -215,127 +180,108 @@ define void @test4() {
|
||||||
; CHECK-LABEL: @test4(
|
; CHECK-LABEL: @test4(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[BANG:%.*]] = alloca [[STRUCT_FOOSTRUCT:%.*]], align 8
|
; CHECK-NEXT: [[BANG:%.*]] = alloca [[STRUCT_FOOSTRUCT:%.*]], align 8
|
||||||
; CHECK-NEXT: [[V2:%.*]] = getelementptr inbounds [[STRUCT_FOOSTRUCT]], %struct.foostruct* [[BANG]], i64 0, i32 0
|
; CHECK-NEXT: store ptr @fa, ptr [[BANG]], align 8
|
||||||
; CHECK-NEXT: store i32 (i8*, i8**, i32, i8, i8*)* @fa, i32 (i8*, i8**, i32, i8, i8*)** [[V2]], align 8
|
; CHECK-NEXT: [[V3:%.*]] = getelementptr inbounds [[STRUCT_FOOSTRUCT]], ptr [[BANG]], i64 0, i32 1
|
||||||
; CHECK-NEXT: [[V3:%.*]] = getelementptr inbounds [[STRUCT_FOOSTRUCT]], %struct.foostruct* [[BANG]], i64 0, i32 1
|
; CHECK-NEXT: store ptr @fa, ptr [[V3]], align 8
|
||||||
; CHECK-NEXT: store i32 (i8*, i8**, i32, i8, i8*)* @fa, i32 (i8*, i8**, i32, i8, i8*)** [[V3]], align 8
|
; CHECK-NEXT: [[V4:%.*]] = getelementptr inbounds [[STRUCT_FOOSTRUCT]], ptr [[BANG]], i64 0, i32 2
|
||||||
; CHECK-NEXT: [[V4:%.*]] = getelementptr inbounds [[STRUCT_FOOSTRUCT]], %struct.foostruct* [[BANG]], i64 0, i32 2
|
; CHECK-NEXT: store ptr @fa, ptr [[V4]], align 8
|
||||||
; CHECK-NEXT: store i32 (i8*, i8**, i32, i8, i8*)* @fa, i32 (i8*, i8**, i32, i8, i8*)** [[V4]], align 8
|
; CHECK-NEXT: [[V5:%.*]] = getelementptr inbounds [[STRUCT_FOOSTRUCT]], ptr [[BANG]], i64 0, i32 3
|
||||||
; CHECK-NEXT: [[V5:%.*]] = getelementptr inbounds [[STRUCT_FOOSTRUCT]], %struct.foostruct* [[BANG]], i64 0, i32 3
|
; CHECK-NEXT: store ptr @fa, ptr [[V5]], align 8
|
||||||
; CHECK-NEXT: store i32 (i8*, i8**, i32, i8, i8*)* @fa, i32 (i8*, i8**, i32, i8, i8*)** [[V5]], align 8
|
; CHECK-NEXT: [[V6:%.*]] = getelementptr inbounds [[STRUCT_FOOSTRUCT]], ptr [[BANG]], i64 0, i32 4
|
||||||
; CHECK-NEXT: [[V6:%.*]] = getelementptr inbounds [[STRUCT_FOOSTRUCT]], %struct.foostruct* [[BANG]], i64 0, i32 4
|
; CHECK-NEXT: store ptr null, ptr [[V6]], align 8
|
||||||
; CHECK-NEXT: store void (i8*, i32, i32)* null, void (i8*, i32, i32)** [[V6]], align 8
|
; CHECK-NEXT: call void @goFunc(ptr [[BANG]])
|
||||||
; CHECK-NEXT: call void @goFunc(%struct.foostruct* [[BANG]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
%bang = alloca %struct.foostruct, align 8
|
%bang = alloca %struct.foostruct, align 8
|
||||||
%v1 = bitcast %struct.foostruct* %bang to i8*
|
call void @llvm.memset.p0.i64(ptr align 8 %bang, i8 0, i64 40, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 8 %v1, i8 0, i64 40, i1 false)
|
store ptr @fa, ptr %bang, align 8
|
||||||
%v2 = getelementptr inbounds %struct.foostruct, %struct.foostruct* %bang, i64 0, i32 0
|
%v3 = getelementptr inbounds %struct.foostruct, ptr %bang, i64 0, i32 1
|
||||||
store i32 (i8*, i8**, i32, i8, i8*)* @fa, i32 (i8*, i8**, i32, i8, i8*)** %v2, align 8
|
store ptr @fa, ptr %v3, align 8
|
||||||
%v3 = getelementptr inbounds %struct.foostruct, %struct.foostruct* %bang, i64 0, i32 1
|
%v4 = getelementptr inbounds %struct.foostruct, ptr %bang, i64 0, i32 2
|
||||||
store i32 (i8*, i8**, i32, i8, i8*)* @fa, i32 (i8*, i8**, i32, i8, i8*)** %v3, align 8
|
store ptr @fa, ptr %v4, align 8
|
||||||
%v4 = getelementptr inbounds %struct.foostruct, %struct.foostruct* %bang, i64 0, i32 2
|
%v5 = getelementptr inbounds %struct.foostruct, ptr %bang, i64 0, i32 3
|
||||||
store i32 (i8*, i8**, i32, i8, i8*)* @fa, i32 (i8*, i8**, i32, i8, i8*)** %v4, align 8
|
store ptr @fa, ptr %v5, align 8
|
||||||
%v5 = getelementptr inbounds %struct.foostruct, %struct.foostruct* %bang, i64 0, i32 3
|
%v6 = getelementptr inbounds %struct.foostruct, ptr %bang, i64 0, i32 4
|
||||||
store i32 (i8*, i8**, i32, i8, i8*)* @fa, i32 (i8*, i8**, i32, i8, i8*)** %v5, align 8
|
store ptr null, ptr %v6, align 8
|
||||||
%v6 = getelementptr inbounds %struct.foostruct, %struct.foostruct* %bang, i64 0, i32 4
|
call void @goFunc(ptr %bang)
|
||||||
store void (i8*, i32, i32)* null, void (i8*, i32, i32)** %v6, align 8
|
|
||||||
call void @goFunc(%struct.foostruct* %bang)
|
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define signext i8 @test5(i32 *%ptr) {
|
define signext i8 @test5(ptr %ptr) {
|
||||||
; CHECK-LABEL: @test5(
|
; CHECK-LABEL: @test5(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[BPTR:%.*]] = bitcast i32* [[PTR:%.*]] to i8*
|
; CHECK-NEXT: [[BPTR1:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[BPTR1:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 1
|
; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 2
|
||||||
; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 2
|
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 3
|
||||||
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 3
|
; CHECK-NEXT: store i16 -1, ptr [[BPTR2]], align 1
|
||||||
; CHECK-NEXT: [[WPTR:%.*]] = bitcast i8* [[BPTR]] to i16*
|
; CHECK-NEXT: store i16 1456, ptr [[BPTR1]], align 1
|
||||||
; CHECK-NEXT: [[WPTR1:%.*]] = bitcast i8* [[BPTR1]] to i16*
|
; CHECK-NEXT: store i16 1346, ptr [[PTR]], align 1
|
||||||
; CHECK-NEXT: [[WPTR2:%.*]] = bitcast i8* [[BPTR2]] to i16*
|
|
||||||
; CHECK-NEXT: store i16 -1, i16* [[WPTR2]], align 1
|
|
||||||
; CHECK-NEXT: store i16 1456, i16* [[WPTR1]], align 1
|
|
||||||
; CHECK-NEXT: store i16 1346, i16* [[WPTR]], align 1
|
|
||||||
; CHECK-NEXT: ret i8 0
|
; CHECK-NEXT: ret i8 0
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
store i32 0, i32* %ptr
|
store i32 0, ptr %ptr
|
||||||
|
|
||||||
%bptr = bitcast i32* %ptr to i8*
|
%bptr1 = getelementptr inbounds i8, ptr %ptr, i64 1
|
||||||
%bptr1 = getelementptr inbounds i8, i8* %bptr, i64 1
|
%bptr2 = getelementptr inbounds i8, ptr %ptr, i64 2
|
||||||
%bptr2 = getelementptr inbounds i8, i8* %bptr, i64 2
|
%bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
||||||
%bptr3 = getelementptr inbounds i8, i8* %bptr, i64 3
|
|
||||||
|
|
||||||
%wptr = bitcast i8* %bptr to i16*
|
|
||||||
%wptr1 = bitcast i8* %bptr1 to i16*
|
|
||||||
%wptr2 = bitcast i8* %bptr2 to i16*
|
|
||||||
|
|
||||||
store i16 65535, i16* %wptr2, align 1
|
store i16 65535, ptr %bptr2, align 1
|
||||||
store i16 1456, i16* %wptr1, align 1
|
store i16 1456, ptr %bptr1, align 1
|
||||||
store i16 1346, i16* %wptr, align 1
|
store i16 1346, ptr %ptr, align 1
|
||||||
|
|
||||||
|
|
||||||
ret i8 0
|
ret i8 0
|
||||||
}
|
}
|
||||||
|
|
||||||
define signext i8 @test6(i32 *%ptr) {
|
define signext i8 @test6(ptr %ptr) {
|
||||||
; CHECK-LABEL: @test6(
|
; CHECK-LABEL: @test6(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[BPTR:%.*]] = bitcast i32* [[PTR:%.*]] to i16*
|
; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i16, ptr [[PTR:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[BPTR1:%.*]] = getelementptr inbounds i16, i16* [[BPTR]], i64 0
|
; CHECK-NEXT: store i16 1456, ptr [[BPTR2]], align 1
|
||||||
; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i16, i16* [[BPTR]], i64 1
|
; CHECK-NEXT: store i16 -1, ptr [[PTR]], align 1
|
||||||
; CHECK-NEXT: store i16 1456, i16* [[BPTR2]], align 1
|
|
||||||
; CHECK-NEXT: store i16 -1, i16* [[BPTR1]], align 1
|
|
||||||
; CHECK-NEXT: ret i8 0
|
; CHECK-NEXT: ret i8 0
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
store i32 0, i32* %ptr
|
store i32 0, ptr %ptr
|
||||||
|
|
||||||
%bptr = bitcast i32* %ptr to i16*
|
%bptr2 = getelementptr inbounds i16, ptr %ptr, i64 1
|
||||||
%bptr1 = getelementptr inbounds i16, i16* %bptr, i64 0
|
|
||||||
%bptr2 = getelementptr inbounds i16, i16* %bptr, i64 1
|
|
||||||
|
|
||||||
store i16 1456, i16* %bptr2, align 1
|
store i16 1456, ptr %bptr2, align 1
|
||||||
store i16 65535, i16* %bptr1, align 1
|
store i16 65535, ptr %ptr, align 1
|
||||||
|
|
||||||
|
|
||||||
ret i8 0
|
ret i8 0
|
||||||
}
|
}
|
||||||
|
|
||||||
define signext i8 @test7(i64 *%ptr) {
|
define signext i8 @test7(ptr %ptr) {
|
||||||
; CHECK-LABEL: @test7(
|
; CHECK-LABEL: @test7(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[BPTR:%.*]] = bitcast i64* [[PTR:%.*]] to i16*
|
; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i16, ptr [[PTR:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[BPTR1:%.*]] = getelementptr inbounds i16, i16* [[BPTR]], i64 0
|
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i16, ptr [[PTR]], i64 2
|
||||||
; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i16, i16* [[BPTR]], i64 1
|
; CHECK-NEXT: [[BPTR4:%.*]] = getelementptr inbounds i16, ptr [[PTR]], i64 3
|
||||||
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i16, i16* [[BPTR]], i64 2
|
; CHECK-NEXT: store i16 1346, ptr [[PTR]], align 1
|
||||||
; CHECK-NEXT: [[BPTR4:%.*]] = getelementptr inbounds i16, i16* [[BPTR]], i64 3
|
; CHECK-NEXT: store i16 1756, ptr [[BPTR3]], align 1
|
||||||
; CHECK-NEXT: store i16 1346, i16* [[BPTR1]], align 1
|
; CHECK-NEXT: store i16 1456, ptr [[BPTR2]], align 1
|
||||||
; CHECK-NEXT: store i16 1756, i16* [[BPTR3]], align 1
|
; CHECK-NEXT: store i16 5656, ptr [[BPTR4]], align 1
|
||||||
; CHECK-NEXT: store i16 1456, i16* [[BPTR2]], align 1
|
|
||||||
; CHECK-NEXT: store i16 5656, i16* [[BPTR4]], align 1
|
|
||||||
; CHECK-NEXT: ret i8 0
|
; CHECK-NEXT: ret i8 0
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
store i64 0, i64* %ptr
|
store i64 0, ptr %ptr
|
||||||
|
|
||||||
%bptr = bitcast i64* %ptr to i16*
|
%bptr2 = getelementptr inbounds i16, ptr %ptr, i64 1
|
||||||
%bptr1 = getelementptr inbounds i16, i16* %bptr, i64 0
|
%bptr3 = getelementptr inbounds i16, ptr %ptr, i64 2
|
||||||
%bptr2 = getelementptr inbounds i16, i16* %bptr, i64 1
|
%bptr4 = getelementptr inbounds i16, ptr %ptr, i64 3
|
||||||
%bptr3 = getelementptr inbounds i16, i16* %bptr, i64 2
|
|
||||||
%bptr4 = getelementptr inbounds i16, i16* %bptr, i64 3
|
|
||||||
|
|
||||||
store i16 1346, i16* %bptr1, align 1
|
store i16 1346, ptr %ptr, align 1
|
||||||
store i16 1756, i16* %bptr3, align 1
|
store i16 1756, ptr %bptr3, align 1
|
||||||
store i16 1456, i16* %bptr2, align 1
|
store i16 1456, ptr %bptr2, align 1
|
||||||
store i16 5656, i16* %bptr4, align 1
|
store i16 5656, ptr %bptr4, align 1
|
||||||
|
|
||||||
|
|
||||||
ret i8 0
|
ret i8 0
|
||||||
|
|
|
@ -5,12 +5,11 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
|
|
||||||
@g = global i32 42
|
@g = global i32 42
|
||||||
|
|
||||||
define void @test1(%t* noalias %pp) {
|
define void @test1(ptr noalias %pp) {
|
||||||
%p = getelementptr inbounds %t, %t* %pp, i32 0, i32 0
|
|
||||||
|
|
||||||
store i32 1, i32* %p; <-- This is dead
|
store i32 1, ptr %pp; <-- This is dead
|
||||||
%x = load i32, i32* inttoptr (i32 12345 to i32*)
|
%x = load i32, ptr inttoptr (i32 12345 to ptr)
|
||||||
store i32 %x, i32* %p
|
store i32 %x, ptr %pp
|
||||||
ret void
|
ret void
|
||||||
; CHECK-LABEL: define void @test1(
|
; CHECK-LABEL: define void @test1(
|
||||||
; CHECK: store
|
; CHECK: store
|
||||||
|
@ -19,8 +18,8 @@ define void @test1(%t* noalias %pp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test3() {
|
define void @test3() {
|
||||||
store i32 1, i32* @g; <-- This is dead.
|
store i32 1, ptr @g; <-- This is dead.
|
||||||
store i32 42, i32* @g
|
store i32 42, ptr @g
|
||||||
ret void
|
ret void
|
||||||
; CHECK-LABEL: define void @test3(
|
; CHECK-LABEL: define void @test3(
|
||||||
; CHECK: store
|
; CHECK: store
|
||||||
|
@ -28,10 +27,10 @@ define void @test3() {
|
||||||
; CHECK: ret void
|
; CHECK: ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test4(i32* %p) {
|
define void @test4(ptr %p) {
|
||||||
store i32 1, i32* %p
|
store i32 1, ptr %p
|
||||||
%x = load i32, i32* @g; <-- %p and @g could alias
|
%x = load i32, ptr @g; <-- %p and @g could alias
|
||||||
store i32 %x, i32* %p
|
store i32 %x, ptr %p
|
||||||
ret void
|
ret void
|
||||||
; CHECK-LABEL: define void @test4(
|
; CHECK-LABEL: define void @test4(
|
||||||
; CHECK: store
|
; CHECK: store
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
||||||
target triple = "i386-apple-darwin10.0"
|
target triple = "i386-apple-darwin10.0"
|
||||||
|
|
||||||
@g80 = external global i8 ; <i8*> [#uses=3]
|
@g80 = external global i8 ; <ptr> [#uses=3]
|
||||||
|
|
||||||
declare signext i8 @foo(i8 signext, i8 signext) nounwind readnone ssp
|
declare signext i8 @foo(i8 signext, i8 signext) nounwind readnone ssp
|
||||||
|
|
||||||
|
@ -16,31 +16,28 @@ entry:
|
||||||
|
|
||||||
bb: ; preds = %bb, %entry
|
bb: ; preds = %bb, %entry
|
||||||
%storemerge = phi i8 [ %2, %bb ], [ 1, %entry ] ; <i8> [#uses=1]
|
%storemerge = phi i8 [ %2, %bb ], [ 1, %entry ] ; <i8> [#uses=1]
|
||||||
store i8 %storemerge, i8* @g80
|
store i8 %storemerge, ptr @g80
|
||||||
%0 = tail call i32 @func68(i32 1) nounwind ssp ; <i32> [#uses=1]
|
%0 = tail call i32 @func68(i32 1) nounwind ssp ; <i32> [#uses=1]
|
||||||
%1 = trunc i32 %0 to i8 ; <i8> [#uses=1]
|
%1 = trunc i32 %0 to i8 ; <i8> [#uses=1]
|
||||||
store i8 %1, i8* @g80, align 1
|
store i8 %1, ptr @g80, align 1
|
||||||
store i8 undef, i8* @g80, align 1
|
store i8 undef, ptr @g80, align 1
|
||||||
%2 = tail call signext i8 @foo(i8 signext undef, i8 signext 1) nounwind ; <i8> [#uses=1]
|
%2 = tail call signext i8 @foo(i8 signext undef, i8 signext 1) nounwind ; <i8> [#uses=1]
|
||||||
br label %bb
|
br label %bb
|
||||||
}
|
}
|
||||||
|
|
||||||
define fastcc i32 @test2() nounwind ssp {
|
define fastcc i32 @test2() nounwind ssp {
|
||||||
bb14: ; preds = %bb4
|
bb14: ; preds = %bb4
|
||||||
%0 = bitcast i8* undef to i8** ; <i8**> [#uses=1]
|
%0 = getelementptr inbounds ptr, ptr undef, i64 undef ; <ptr> [#uses=1]
|
||||||
%1 = getelementptr inbounds i8*, i8** %0, i64 undef ; <i8**> [#uses=1]
|
%1 = getelementptr inbounds i16, ptr %0, i64 undef ; <ptr> [#uses=1]
|
||||||
%2 = bitcast i8** %1 to i16* ; <i16*> [#uses=2]
|
%2 = getelementptr inbounds i8, ptr %1, i64 undef ; <ptr> [#uses=1]
|
||||||
%3 = getelementptr inbounds i16, i16* %2, i64 undef ; <i16*> [#uses=1]
|
%3 = getelementptr inbounds i16, ptr %0, i64 undef ; <ptr> [#uses=1]
|
||||||
%4 = bitcast i16* %3 to i8* ; <i8*> [#uses=1]
|
store i16 undef, ptr %3, align 2
|
||||||
%5 = getelementptr inbounds i8, i8* %4, i64 undef ; <i8*> [#uses=1]
|
%4 = getelementptr inbounds i8, ptr %2, i64 undef ; <ptr> [#uses=1]
|
||||||
%6 = getelementptr inbounds i16, i16* %2, i64 undef ; <i16*> [#uses=1]
|
call void @llvm.memcpy.p0.p0.i64(ptr %4, ptr undef, i64 undef, i1 false)
|
||||||
store i16 undef, i16* %6, align 2
|
|
||||||
%7 = getelementptr inbounds i8, i8* %5, i64 undef ; <i8*> [#uses=1]
|
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %7, i8* undef, i64 undef, i1 false)
|
|
||||||
unreachable
|
unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
|
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind
|
||||||
|
|
||||||
|
|
||||||
; rdar://7635088
|
; rdar://7635088
|
||||||
|
@ -49,26 +46,26 @@ entry:
|
||||||
ret i32 0
|
ret i32 0
|
||||||
|
|
||||||
dead:
|
dead:
|
||||||
%P2 = getelementptr i32, i32 *%P2, i32 52
|
%P2 = getelementptr i32, ptr %P2, i32 52
|
||||||
%Q2 = getelementptr i32, i32 *%Q2, i32 52
|
%Q2 = getelementptr i32, ptr %Q2, i32 52
|
||||||
store i32 4, i32* %P2
|
store i32 4, ptr %P2
|
||||||
store i32 4, i32* %Q2
|
store i32 4, ptr %Q2
|
||||||
br label %dead
|
br label %dead
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
; PR3141
|
; PR3141
|
||||||
%struct.ada__tags__dispatch_table = type { [1 x i32] }
|
%struct.ada__tags__dispatch_table = type { [1 x i32] }
|
||||||
%struct.f393a00_1__object = type { %struct.ada__tags__dispatch_table*, i8 }
|
%struct.f393a00_1__object = type { ptr, i8 }
|
||||||
%struct.f393a00_2__windmill = type { %struct.f393a00_1__object, i16 }
|
%struct.f393a00_2__windmill = type { %struct.f393a00_1__object, i16 }
|
||||||
|
|
||||||
define void @test4(%struct.f393a00_2__windmill* %a, %struct.f393a00_2__windmill* %b) {
|
define void @test4(ptr %a, ptr %b) {
|
||||||
entry:
|
entry:
|
||||||
%t = alloca %struct.f393a00_2__windmill ; <%struct.f393a00_2__windmill*> [#uses=1]
|
%t = alloca %struct.f393a00_2__windmill ; <ptr> [#uses=1]
|
||||||
%0 = getelementptr %struct.f393a00_2__windmill, %struct.f393a00_2__windmill* %t, i32 0, i32 0, i32 0 ; <%struct.ada__tags__dispatch_table**> [#uses=1]
|
%0 = getelementptr %struct.f393a00_2__windmill, ptr %t, i32 0, i32 0, i32 0 ; <ptr> [#uses=1]
|
||||||
%1 = load %struct.ada__tags__dispatch_table*, %struct.ada__tags__dispatch_table** null, align 4 ; <%struct.ada__tags__dispatch_table*> [#uses=1]
|
%1 = load ptr, ptr null, align 4 ; <ptr> [#uses=1]
|
||||||
%2 = load %struct.ada__tags__dispatch_table*, %struct.ada__tags__dispatch_table** %0, align 8 ; <%struct.ada__tags__dispatch_table*> [#uses=1]
|
%2 = load ptr, ptr %0, align 8 ; <ptr> [#uses=1]
|
||||||
store %struct.ada__tags__dispatch_table* %2, %struct.ada__tags__dispatch_table** null, align 4
|
store ptr %2, ptr null, align 4
|
||||||
store %struct.ada__tags__dispatch_table* %1, %struct.ada__tags__dispatch_table** null, align 4
|
store ptr %1, ptr null, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,14 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||||
%class.basic_string = type { %"class.__gnu_cxx::__versa_string" }
|
%class.basic_string = type { %"class.__gnu_cxx::__versa_string" }
|
||||||
%"class.__gnu_cxx::__versa_string" = type { %"class.__gnu_cxx::__sso_string_base" }
|
%"class.__gnu_cxx::__versa_string" = type { %"class.__gnu_cxx::__sso_string_base" }
|
||||||
%"class.__gnu_cxx::__sso_string_base" = type { %"struct.__gnu_cxx::__vstring_utility<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider", i64, %union.anon }
|
%"class.__gnu_cxx::__sso_string_base" = type { %"struct.__gnu_cxx::__vstring_utility<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider", i64, %union.anon }
|
||||||
%"struct.__gnu_cxx::__vstring_utility<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider" = type { i8* }
|
%"struct.__gnu_cxx::__vstring_utility<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider" = type { ptr }
|
||||||
%union.anon = type { i64, [8 x i8] }
|
%union.anon = type { i64, [8 x i8] }
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) #0
|
declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1) #0
|
||||||
|
|
||||||
; Function Attrs: noinline nounwind readonly uwtable
|
; Function Attrs: noinline nounwind readonly uwtable
|
||||||
declare zeroext i1 @callee_takes_string(%class.basic_string* nonnull) #1 align 2
|
declare zeroext i1 @callee_takes_string(ptr nonnull) #1 align 2
|
||||||
|
|
||||||
; Function Attrs: nounwind uwtable
|
; Function Attrs: nounwind uwtable
|
||||||
define weak_odr zeroext i1 @test() #2 align 2 {
|
define weak_odr zeroext i1 @test() #2 align 2 {
|
||||||
|
@ -22,27 +22,21 @@ define weak_odr zeroext i1 @test() #2 align 2 {
|
||||||
bb:
|
bb:
|
||||||
%tmp = alloca %class.basic_string, align 8
|
%tmp = alloca %class.basic_string, align 8
|
||||||
%tmp1 = alloca %class.basic_string, align 8
|
%tmp1 = alloca %class.basic_string, align 8
|
||||||
%tmp3 = getelementptr inbounds %class.basic_string, %class.basic_string* %tmp, i64 0, i32 0, i32 0, i32 2
|
%tmp3 = getelementptr inbounds %class.basic_string, ptr %tmp, i64 0, i32 0, i32 0, i32 2
|
||||||
%tmp4 = bitcast %union.anon* %tmp3 to i8*
|
%tmp6 = getelementptr inbounds %class.basic_string, ptr %tmp, i64 0, i32 0, i32 0, i32 1
|
||||||
%tmp5 = getelementptr inbounds %class.basic_string, %class.basic_string* %tmp, i64 0, i32 0, i32 0, i32 0, i32 0
|
%tmp7 = getelementptr inbounds i8, ptr %tmp3, i64 1
|
||||||
%tmp6 = getelementptr inbounds %class.basic_string, %class.basic_string* %tmp, i64 0, i32 0, i32 0, i32 1
|
|
||||||
%tmp7 = getelementptr inbounds i8, i8* %tmp4, i64 1
|
|
||||||
%tmp8 = bitcast %class.basic_string* %tmp to i8*
|
|
||||||
%tmp9 = bitcast i64 0 to i64
|
%tmp9 = bitcast i64 0 to i64
|
||||||
%tmp10 = getelementptr inbounds %class.basic_string, %class.basic_string* %tmp1, i64 0, i32 0, i32 0, i32 2
|
%tmp10 = getelementptr inbounds %class.basic_string, ptr %tmp1, i64 0, i32 0, i32 0, i32 2
|
||||||
%tmp11 = bitcast %union.anon* %tmp10 to i8*
|
%tmp13 = getelementptr inbounds %class.basic_string, ptr %tmp1, i64 0, i32 0, i32 0, i32 1
|
||||||
%tmp12 = getelementptr inbounds %class.basic_string, %class.basic_string* %tmp1, i64 0, i32 0, i32 0, i32 0, i32 0
|
%tmp14 = getelementptr inbounds i8, ptr %tmp10, i64 1
|
||||||
%tmp13 = getelementptr inbounds %class.basic_string, %class.basic_string* %tmp1, i64 0, i32 0, i32 0, i32 1
|
|
||||||
%tmp14 = getelementptr inbounds i8, i8* %tmp11, i64 1
|
|
||||||
%tmp15 = bitcast %class.basic_string* %tmp1 to i8*
|
|
||||||
br label %_ZN12basic_stringIcSt11char_traitsIcESaIcEEC2EPKcRKS2_.exit
|
br label %_ZN12basic_stringIcSt11char_traitsIcESaIcEEC2EPKcRKS2_.exit
|
||||||
|
|
||||||
_ZN12basic_stringIcSt11char_traitsIcESaIcEEC2EPKcRKS2_.exit: ; preds = %bb
|
_ZN12basic_stringIcSt11char_traitsIcESaIcEEC2EPKcRKS2_.exit: ; preds = %bb
|
||||||
store i8* %tmp4, i8** %tmp5, align 8
|
store ptr %tmp3, ptr %tmp, align 8
|
||||||
store i8 62, i8* %tmp4, align 8
|
store i8 62, ptr %tmp3, align 8
|
||||||
store i64 1, i64* %tmp6, align 8
|
store i64 1, ptr %tmp6, align 8
|
||||||
store i8 0, i8* %tmp7, align 1
|
store i8 0, ptr %tmp7, align 1
|
||||||
%tmp16 = call zeroext i1 @callee_takes_string(%class.basic_string* nonnull %tmp)
|
%tmp16 = call zeroext i1 @callee_takes_string(ptr nonnull %tmp)
|
||||||
br label %_ZN9__gnu_cxx17__sso_string_baseIcSt11char_traitsIcESaIcEED2Ev.exit3
|
br label %_ZN9__gnu_cxx17__sso_string_baseIcSt11char_traitsIcESaIcEED2Ev.exit3
|
||||||
|
|
||||||
_ZN9__gnu_cxx17__sso_string_baseIcSt11char_traitsIcESaIcEED2Ev.exit3: ; preds = %_ZN12basic_stringIcSt11char_traitsIcESaIcEEC2EPKcRKS2_.exit
|
_ZN9__gnu_cxx17__sso_string_baseIcSt11char_traitsIcESaIcEED2Ev.exit3: ; preds = %_ZN12basic_stringIcSt11char_traitsIcESaIcEEC2EPKcRKS2_.exit
|
||||||
|
@ -50,21 +44,21 @@ _ZN9__gnu_cxx17__sso_string_baseIcSt11char_traitsIcESaIcEED2Ev.exit3: ; preds =
|
||||||
; CHECK: _ZN9__gnu_cxx17__sso_string_baseIcSt11char_traitsIcESaIcEED2Ev.exit3:
|
; CHECK: _ZN9__gnu_cxx17__sso_string_baseIcSt11char_traitsIcESaIcEED2Ev.exit3:
|
||||||
|
|
||||||
; The following can be read through the call %tmp17:
|
; The following can be read through the call %tmp17:
|
||||||
store i8* %tmp11, i8** %tmp12, align 8
|
store ptr %tmp10, ptr %tmp1, align 8
|
||||||
store i8 125, i8* %tmp11, align 8
|
store i8 125, ptr %tmp10, align 8
|
||||||
store i64 1, i64* %tmp13, align 8
|
store i64 1, ptr %tmp13, align 8
|
||||||
store i8 0, i8* %tmp14, align 1
|
store i8 0, ptr %tmp14, align 1
|
||||||
|
|
||||||
; CHECK: store i8* %tmp11, i8** %tmp12, align 8
|
; CHECK: store ptr %tmp10, ptr %tmp1, align 8
|
||||||
; CHECK: store i8 125, i8* %tmp11, align 8
|
; CHECK: store i8 125, ptr %tmp10, align 8
|
||||||
; CHECK: store i64 1, i64* %tmp13, align 8
|
; CHECK: store i64 1, ptr %tmp13, align 8
|
||||||
; CHECK: store i8 0, i8* %tmp14, align 1
|
; CHECK: store i8 0, ptr %tmp14, align 1
|
||||||
|
|
||||||
%tmp17 = call zeroext i1 @callee_takes_string(%class.basic_string* nonnull %tmp1)
|
%tmp17 = call zeroext i1 @callee_takes_string(ptr nonnull %tmp1)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 8 %tmp11, i8 -51, i64 16, i1 false) #0
|
call void @llvm.memset.p0.i64(ptr align 8 %tmp10, i8 -51, i64 16, i1 false) #0
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 8 %tmp15, i8 -51, i64 32, i1 false) #0
|
call void @llvm.memset.p0.i64(ptr align 8 %tmp1, i8 -51, i64 32, i1 false) #0
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 8 %tmp4, i8 -51, i64 16, i1 false) #0
|
call void @llvm.memset.p0.i64(ptr align 8 %tmp3, i8 -51, i64 16, i1 false) #0
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 8 %tmp8, i8 -51, i64 32, i1 false) #0
|
call void @llvm.memset.p0.i64(ptr align 8 %tmp, i8 -51, i64 32, i1 false) #0
|
||||||
ret i1 %tmp17
|
ret i1 %tmp17
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,31 +18,31 @@
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||||
|
|
||||||
|
|
||||||
define void @test(i32* noalias %P, i32* noalias %Q, i32* noalias %R) {
|
define void @test(ptr noalias %P, ptr noalias %Q, ptr noalias %R) {
|
||||||
; SKIP0-COUNT1-LABEL: @test(
|
; SKIP0-COUNT1-LABEL: @test(
|
||||||
; SKIP0-COUNT1-NEXT: store i32 1, i32* [[P:%.*]]
|
; SKIP0-COUNT1-NEXT: store i32 1, ptr [[P:%.*]]
|
||||||
; SKIP0-COUNT1-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; SKIP0-COUNT1-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; SKIP0-COUNT1: bb1:
|
; SKIP0-COUNT1: bb1:
|
||||||
; SKIP0-COUNT1-NEXT: br label [[BB3:%.*]]
|
; SKIP0-COUNT1-NEXT: br label [[BB3:%.*]]
|
||||||
; SKIP0-COUNT1: bb2:
|
; SKIP0-COUNT1: bb2:
|
||||||
; SKIP0-COUNT1-NEXT: br label [[BB3]]
|
; SKIP0-COUNT1-NEXT: br label [[BB3]]
|
||||||
; SKIP0-COUNT1: bb3:
|
; SKIP0-COUNT1: bb3:
|
||||||
; SKIP0-COUNT1-NEXT: store i32 0, i32* [[Q:%.*]]
|
; SKIP0-COUNT1-NEXT: store i32 0, ptr [[Q:%.*]]
|
||||||
; SKIP0-COUNT1-NEXT: store i32 0, i32* [[R:%.*]]
|
; SKIP0-COUNT1-NEXT: store i32 0, ptr [[R:%.*]]
|
||||||
; SKIP0-COUNT1-NEXT: store i32 0, i32* [[P]]
|
; SKIP0-COUNT1-NEXT: store i32 0, ptr [[P]]
|
||||||
; SKIP0-COUNT1-NEXT: ret void
|
; SKIP0-COUNT1-NEXT: ret void
|
||||||
;
|
;
|
||||||
; SKIP1-COUNT1-LABEL: @test(
|
; SKIP1-COUNT1-LABEL: @test(
|
||||||
; SKIP1-COUNT1-NEXT: store i32 1, i32* [[R:%.*]]
|
; SKIP1-COUNT1-NEXT: store i32 1, ptr [[R:%.*]]
|
||||||
; SKIP1-COUNT1-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; SKIP1-COUNT1-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; SKIP1-COUNT1: bb1:
|
; SKIP1-COUNT1: bb1:
|
||||||
; SKIP1-COUNT1-NEXT: br label [[BB3:%.*]]
|
; SKIP1-COUNT1-NEXT: br label [[BB3:%.*]]
|
||||||
; SKIP1-COUNT1: bb2:
|
; SKIP1-COUNT1: bb2:
|
||||||
; SKIP1-COUNT1-NEXT: br label [[BB3]]
|
; SKIP1-COUNT1-NEXT: br label [[BB3]]
|
||||||
; SKIP1-COUNT1: bb3:
|
; SKIP1-COUNT1: bb3:
|
||||||
; SKIP1-COUNT1-NEXT: store i32 0, i32* [[Q:%.*]]
|
; SKIP1-COUNT1-NEXT: store i32 0, ptr [[Q:%.*]]
|
||||||
; SKIP1-COUNT1-NEXT: store i32 0, i32* [[R]]
|
; SKIP1-COUNT1-NEXT: store i32 0, ptr [[R]]
|
||||||
; SKIP1-COUNT1-NEXT: store i32 0, i32* [[P:%.*]]
|
; SKIP1-COUNT1-NEXT: store i32 0, ptr [[P:%.*]]
|
||||||
; SKIP1-COUNT1-NEXT: ret void
|
; SKIP1-COUNT1-NEXT: ret void
|
||||||
;
|
;
|
||||||
; SKIP0-COUNT2-LABEL: @test(
|
; SKIP0-COUNT2-LABEL: @test(
|
||||||
|
@ -52,35 +52,35 @@ define void @test(i32* noalias %P, i32* noalias %Q, i32* noalias %R) {
|
||||||
; SKIP0-COUNT2: bb2:
|
; SKIP0-COUNT2: bb2:
|
||||||
; SKIP0-COUNT2-NEXT: br label [[BB3]]
|
; SKIP0-COUNT2-NEXT: br label [[BB3]]
|
||||||
; SKIP0-COUNT2: bb3:
|
; SKIP0-COUNT2: bb3:
|
||||||
; SKIP0-COUNT2-NEXT: store i32 0, i32* [[Q:%.*]]
|
; SKIP0-COUNT2-NEXT: store i32 0, ptr [[Q:%.*]]
|
||||||
; SKIP0-COUNT2-NEXT: store i32 0, i32* [[R:%.*]]
|
; SKIP0-COUNT2-NEXT: store i32 0, ptr [[R:%.*]]
|
||||||
; SKIP0-COUNT2-NEXT: store i32 0, i32* [[P:%.*]]
|
; SKIP0-COUNT2-NEXT: store i32 0, ptr [[P:%.*]]
|
||||||
; SKIP0-COUNT2-NEXT: ret void
|
; SKIP0-COUNT2-NEXT: ret void
|
||||||
;
|
;
|
||||||
; SKIP2-COUNT1-LABEL: @test(
|
; SKIP2-COUNT1-LABEL: @test(
|
||||||
; SKIP2-COUNT1-NEXT: store i32 1, i32* [[P:%.*]]
|
; SKIP2-COUNT1-NEXT: store i32 1, ptr [[P:%.*]]
|
||||||
; SKIP2-COUNT1-NEXT: store i32 1, i32* [[R:%.*]]
|
; SKIP2-COUNT1-NEXT: store i32 1, ptr [[R:%.*]]
|
||||||
; SKIP2-COUNT1-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; SKIP2-COUNT1-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; SKIP2-COUNT1: bb1:
|
; SKIP2-COUNT1: bb1:
|
||||||
; SKIP2-COUNT1-NEXT: br label [[BB3:%.*]]
|
; SKIP2-COUNT1-NEXT: br label [[BB3:%.*]]
|
||||||
; SKIP2-COUNT1: bb2:
|
; SKIP2-COUNT1: bb2:
|
||||||
; SKIP2-COUNT1-NEXT: br label [[BB3]]
|
; SKIP2-COUNT1-NEXT: br label [[BB3]]
|
||||||
; SKIP2-COUNT1: bb3:
|
; SKIP2-COUNT1: bb3:
|
||||||
; SKIP2-COUNT1-NEXT: store i32 0, i32* [[Q:%.*]]
|
; SKIP2-COUNT1-NEXT: store i32 0, ptr [[Q:%.*]]
|
||||||
; SKIP2-COUNT1-NEXT: store i32 0, i32* [[R]]
|
; SKIP2-COUNT1-NEXT: store i32 0, ptr [[R]]
|
||||||
; SKIP2-COUNT1-NEXT: store i32 0, i32* [[P]]
|
; SKIP2-COUNT1-NEXT: store i32 0, ptr [[P]]
|
||||||
; SKIP2-COUNT1-NEXT: ret void
|
; SKIP2-COUNT1-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
store i32 1, i32* %R
|
store i32 1, ptr %R
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
store i32 0, i32* %Q
|
store i32 0, ptr %Q
|
||||||
store i32 0, i32* %R
|
store i32 0, ptr %R
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,30 +2,26 @@
|
||||||
|
|
||||||
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
|
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
|
||||||
|
|
||||||
declare noalias i8* @malloc(i32)
|
declare noalias ptr @malloc(i32)
|
||||||
|
|
||||||
declare void @test_f()
|
declare void @test_f()
|
||||||
|
|
||||||
define i32* @test_salvage(i32 %arg) {
|
define ptr @test_salvage(i32 %arg) {
|
||||||
; Check that all four original local variables have their values preserved.
|
; Check that all four original local variables have their values preserved.
|
||||||
; CHECK-LABEL: @test_salvage(
|
; CHECK-LABEL: @test_salvage(
|
||||||
; CHECK-NEXT: malloc
|
; CHECK-NEXT: malloc
|
||||||
; CHECK-NEXT: @llvm.dbg.value(metadata i8* %p, metadata ![[p:.*]], metadata !DIExpression())
|
; CHECK-NEXT: @llvm.dbg.value(metadata ptr %p, metadata ![[p:.*]], metadata !DIExpression())
|
||||||
; CHECK-NEXT: bitcast
|
|
||||||
; CHECK-NEXT: @llvm.dbg.value(metadata i32* %P, metadata ![[P:.*]], metadata !DIExpression())
|
|
||||||
; CHECK-NEXT: @llvm.dbg.value(metadata i32 %arg, metadata ![[DEAD:.*]], metadata !DIExpression(DW_OP_plus_uconst, 1, DW_OP_stack_value))
|
; CHECK-NEXT: @llvm.dbg.value(metadata i32 %arg, metadata ![[DEAD:.*]], metadata !DIExpression(DW_OP_plus_uconst, 1, DW_OP_stack_value))
|
||||||
; CHECK-NEXT: call void @test_f()
|
; CHECK-NEXT: call void @test_f()
|
||||||
; CHECK-NEXT: store i32 0, i32* %P
|
; CHECK-NEXT: store i32 0, ptr %p
|
||||||
|
|
||||||
%p = tail call i8* @malloc(i32 4)
|
%p = tail call ptr @malloc(i32 4)
|
||||||
%P = bitcast i8* %p to i32*
|
|
||||||
%DEAD = add i32 %arg, 1
|
%DEAD = add i32 %arg, 1
|
||||||
store i32 %DEAD, i32* %P
|
store i32 %DEAD, ptr %p
|
||||||
call void @test_f()
|
call void @test_f()
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %p
|
||||||
ret i32* %P
|
ret ptr %p
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK: ![[p]] = !DILocalVariable(name: "1"
|
; CHECK: ![[p]] = !DILocalVariable(name: "1"
|
||||||
; CHECK: ![[P]] = !DILocalVariable(name: "2"
|
; CHECK: ![[DEAD]] = !DILocalVariable(name: "2"
|
||||||
; CHECK: ![[DEAD]] = !DILocalVariable(name: "3"
|
|
||||||
|
|
|
@ -5,16 +5,15 @@ declare void @bar()
|
||||||
define void @foo() {
|
define void @foo() {
|
||||||
bb1:
|
bb1:
|
||||||
%memtmp3.i = alloca [21 x i8], align 1
|
%memtmp3.i = alloca [21 x i8], align 1
|
||||||
%0 = getelementptr inbounds [21 x i8], [21 x i8]* %memtmp3.i, i64 0, i64 0
|
|
||||||
br label %bb3
|
br label %bb3
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
call void @llvm.lifetime.end.p0i8(i64 -1, i8* %0)
|
call void @llvm.lifetime.end.p0(i64 -1, ptr %memtmp3.i)
|
||||||
br label %bb3
|
br label %bb3
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
call void @bar()
|
call void @bar()
|
||||||
call void @llvm.lifetime.end.p0i8(i64 -1, i8* %0)
|
call void @llvm.lifetime.end.p0(i64 -1, ptr %memtmp3.i)
|
||||||
br label %bb4
|
br label %bb4
|
||||||
|
|
||||||
bb4:
|
bb4:
|
||||||
|
@ -22,4 +21,4 @@ bb4:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) nounwind
|
declare void @llvm.lifetime.end.p0(i64, ptr nocapture) nounwind
|
||||||
|
|
|
@ -7,19 +7,19 @@
|
||||||
; Right now the DSE in presence of fence is only done in end blocks (with no successors),
|
; Right now the DSE in presence of fence is only done in end blocks (with no successors),
|
||||||
; but the same logic applies to other basic blocks as well.
|
; but the same logic applies to other basic blocks as well.
|
||||||
; The store to %addr.i can be removed since it is a byval attribute
|
; The store to %addr.i can be removed since it is a byval attribute
|
||||||
define void @test3(i32* byval(i32) %addr.i) {
|
define void @test3(ptr byval(i32) %addr.i) {
|
||||||
; CHECK-LABEL: @test3
|
; CHECK-LABEL: @test3
|
||||||
; CHECK-NOT: store
|
; CHECK-NOT: store
|
||||||
; CHECK: fence
|
; CHECK: fence
|
||||||
; CHECK: ret
|
; CHECK: ret
|
||||||
store i32 5, i32* %addr.i, align 4
|
store i32 5, ptr %addr.i, align 4
|
||||||
fence release
|
fence release
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @foo(i8* nocapture %p)
|
declare void @foo(ptr nocapture %p)
|
||||||
|
|
||||||
declare noalias i8* @malloc(i32)
|
declare noalias ptr @malloc(i32)
|
||||||
|
|
||||||
; DSE of stores in locations allocated through library calls.
|
; DSE of stores in locations allocated through library calls.
|
||||||
define void @test_nocapture() {
|
define void @test_nocapture() {
|
||||||
|
@ -28,9 +28,9 @@ define void @test_nocapture() {
|
||||||
; CHECK: foo
|
; CHECK: foo
|
||||||
; CHECK-NOT: store
|
; CHECK-NOT: store
|
||||||
; CHECK: fence
|
; CHECK: fence
|
||||||
%m = call i8* @malloc(i32 24)
|
%m = call ptr @malloc(i32 24)
|
||||||
call void @foo(i8* %m)
|
call void @foo(ptr %m)
|
||||||
store i8 4, i8* %m
|
store i8 4, ptr %m
|
||||||
fence release
|
fence release
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -43,8 +43,8 @@ define void @fence_seq_cst() {
|
||||||
; CHECK-NEXT: fence seq_cst
|
; CHECK-NEXT: fence seq_cst
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
%P1 = alloca i32
|
%P1 = alloca i32
|
||||||
store i32 0, i32* %P1, align 4
|
store i32 0, ptr %P1, align 4
|
||||||
fence seq_cst
|
fence seq_cst
|
||||||
store i32 4, i32* %P1, align 4
|
store i32 4, ptr %P1, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,43 +6,43 @@
|
||||||
; it is conservatively correct. A legal optimization
|
; it is conservatively correct. A legal optimization
|
||||||
; could hoist the second store above the fence, and then
|
; could hoist the second store above the fence, and then
|
||||||
; DSE one of them.
|
; DSE one of them.
|
||||||
define void @test1(i32* %addr.i) {
|
define void @test1(ptr %addr.i) {
|
||||||
; CHECK-LABEL: @test1
|
; CHECK-LABEL: @test1
|
||||||
; CHECK: store i32 5
|
; CHECK: store i32 5
|
||||||
; CHECK: fence
|
; CHECK: fence
|
||||||
; CHECK: store i32 5
|
; CHECK: store i32 5
|
||||||
; CHECK: ret
|
; CHECK: ret
|
||||||
store i32 5, i32* %addr.i, align 4
|
store i32 5, ptr %addr.i, align 4
|
||||||
fence release
|
fence release
|
||||||
store i32 5, i32* %addr.i, align 4
|
store i32 5, ptr %addr.i, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Same as previous, but with different values. If we ever optimize
|
; Same as previous, but with different values. If we ever optimize
|
||||||
; this more aggressively, this allows us to check that the correct
|
; this more aggressively, this allows us to check that the correct
|
||||||
; store is retained (the 'i32 1' store in this case)
|
; store is retained (the 'i32 1' store in this case)
|
||||||
define void @test1b(i32* %addr.i) {
|
define void @test1b(ptr %addr.i) {
|
||||||
; CHECK-LABEL: @test1b
|
; CHECK-LABEL: @test1b
|
||||||
; CHECK: store i32 42
|
; CHECK: store i32 42
|
||||||
; CHECK: fence release
|
; CHECK: fence release
|
||||||
; CHECK: store i32 1
|
; CHECK: store i32 1
|
||||||
; CHECK: ret
|
; CHECK: ret
|
||||||
store i32 42, i32* %addr.i, align 4
|
store i32 42, ptr %addr.i, align 4
|
||||||
fence release
|
fence release
|
||||||
store i32 1, i32* %addr.i, align 4
|
store i32 1, ptr %addr.i, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; We *could* DSE across this fence, but don't. No other thread can
|
; We *could* DSE across this fence, but don't. No other thread can
|
||||||
; observe the order of the acquire fence and the store.
|
; observe the order of the acquire fence and the store.
|
||||||
define void @test2(i32* %addr.i) {
|
define void @test2(ptr %addr.i) {
|
||||||
; CHECK-LABEL: @test2
|
; CHECK-LABEL: @test2
|
||||||
; CHECK: store
|
; CHECK: store
|
||||||
; CHECK: fence
|
; CHECK: fence
|
||||||
; CHECK: store
|
; CHECK: store
|
||||||
; CHECK: ret
|
; CHECK: ret
|
||||||
store i32 5, i32* %addr.i, align 4
|
store i32 5, ptr %addr.i, align 4
|
||||||
fence acquire
|
fence acquire
|
||||||
store i32 5, i32* %addr.i, align 4
|
store i32 5, ptr %addr.i, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,46 +3,42 @@
|
||||||
|
|
||||||
target datalayout = "e-p:64:64:64"
|
target datalayout = "e-p:64:64:64"
|
||||||
|
|
||||||
declare void @free(i8* nocapture) allockind("free")
|
declare void @free(ptr nocapture) allockind("free")
|
||||||
declare noalias i8* @malloc(i64) allockind("alloc,uninitialized")
|
declare noalias ptr @malloc(i64) allockind("alloc,uninitialized")
|
||||||
|
|
||||||
define void @test(i32* %Q, i32* %P) {
|
define void @test(ptr %Q, ptr %P) {
|
||||||
; CHECK-LABEL: @test(
|
; CHECK-LABEL: @test(
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[P:%.*]] to i8*
|
; CHECK-NEXT: tail call void @free(ptr [[P:%.*]]) [[ATTR0:#.*]]
|
||||||
; CHECK-NEXT: tail call void @free(i8* [[TMP1]]) [[ATTR0:#.*]]
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%DEAD = load i32, i32* %Q ; <i32> [#uses=1]
|
%DEAD = load i32, ptr %Q ; <i32> [#uses=1]
|
||||||
store i32 %DEAD, i32* %P
|
store i32 %DEAD, ptr %P
|
||||||
%1 = bitcast i32* %P to i8*
|
tail call void @free(ptr %P) nounwind
|
||||||
tail call void @free(i8* %1) nounwind
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test2({i32, i32}* %P) {
|
define void @test2(ptr %P) {
|
||||||
; CHECK-LABEL: @test2(
|
; CHECK-LABEL: @test2(
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = bitcast { i32, i32 }* [[P:%.*]] to i8*
|
; CHECK-NEXT: tail call void @free(ptr [[P:%.*]]) [[ATTR0]]
|
||||||
; CHECK-NEXT: tail call void @free(i8* [[TMP1]]) [[ATTR0]]
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%Q = getelementptr {i32, i32}, {i32, i32} *%P, i32 0, i32 1
|
%Q = getelementptr {i32, i32}, ptr %P, i32 0, i32 1
|
||||||
store i32 4, i32* %Q
|
store i32 4, ptr %Q
|
||||||
%1 = bitcast {i32, i32}* %P to i8*
|
tail call void @free(ptr %P) nounwind
|
||||||
tail call void @free(i8* %1) nounwind
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test3() {
|
define void @test3() {
|
||||||
; CHECK-LABEL: @test3(
|
; CHECK-LABEL: @test3(
|
||||||
; CHECK-NEXT: [[M:%.*]] = call i8* @malloc(i64 24)
|
; CHECK-NEXT: [[M:%.*]] = call ptr @malloc(i64 24)
|
||||||
; CHECK-NEXT: call void @free(i8* [[M]]) [[ATTR0]]
|
; CHECK-NEXT: call void @free(ptr [[M]]) [[ATTR0]]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%m = call i8* @malloc(i64 24)
|
%m = call ptr @malloc(i64 24)
|
||||||
store i8 0, i8* %m
|
store i8 0, ptr %m
|
||||||
%m1 = getelementptr i8, i8* %m, i64 1
|
%m1 = getelementptr i8, ptr %m, i64 1
|
||||||
store i8 1, i8* %m1
|
store i8 1, ptr %m1
|
||||||
call void @free(i8* %m) nounwind
|
call void @free(ptr %m) nounwind
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,24 +46,24 @@ define void @test3() {
|
||||||
define void @test4(i1 %x) nounwind {
|
define void @test4(i1 %x) nounwind {
|
||||||
; CHECK-LABEL: @test4(
|
; CHECK-LABEL: @test4(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[ALLOC1:%.*]] = tail call noalias i8* @malloc(i64 4) [[ATTR0]]
|
; CHECK-NEXT: [[ALLOC1:%.*]] = tail call noalias ptr @malloc(i64 4) [[ATTR0]]
|
||||||
; CHECK-NEXT: br i1 [[X:%.*]], label [[SKIPINIT1:%.*]], label [[INIT1:%.*]]
|
; CHECK-NEXT: br i1 [[X:%.*]], label [[SKIPINIT1:%.*]], label [[INIT1:%.*]]
|
||||||
; CHECK: init1:
|
; CHECK: init1:
|
||||||
; CHECK-NEXT: br label [[SKIPINIT1]]
|
; CHECK-NEXT: br label [[SKIPINIT1]]
|
||||||
; CHECK: skipinit1:
|
; CHECK: skipinit1:
|
||||||
; CHECK-NEXT: tail call void @free(i8* [[ALLOC1]]) [[ATTR0]]
|
; CHECK-NEXT: tail call void @free(ptr [[ALLOC1]]) [[ATTR0]]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%alloc1 = tail call noalias i8* @malloc(i64 4) nounwind
|
%alloc1 = tail call noalias ptr @malloc(i64 4) nounwind
|
||||||
br i1 %x, label %skipinit1, label %init1
|
br i1 %x, label %skipinit1, label %init1
|
||||||
|
|
||||||
init1:
|
init1:
|
||||||
store i8 1, i8* %alloc1
|
store i8 1, ptr %alloc1
|
||||||
br label %skipinit1
|
br label %skipinit1
|
||||||
|
|
||||||
skipinit1:
|
skipinit1:
|
||||||
tail call void @free(i8* %alloc1) nounwind
|
tail call void @free(ptr %alloc1) nounwind
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,13 +71,13 @@ define void @test5() {
|
||||||
; CHECK-LABEL: @test5(
|
; CHECK-LABEL: @test5(
|
||||||
; CHECK-NEXT: br label [[BB:%.*]]
|
; CHECK-NEXT: br label [[BB:%.*]]
|
||||||
; CHECK: bb:
|
; CHECK: bb:
|
||||||
; CHECK-NEXT: tail call void @free(i8* undef) [[ATTR0]]
|
; CHECK-NEXT: tail call void @free(ptr undef) [[ATTR0]]
|
||||||
; CHECK-NEXT: br label [[BB]]
|
; CHECK-NEXT: br label [[BB]]
|
||||||
;
|
;
|
||||||
br label %bb
|
br label %bb
|
||||||
|
|
||||||
bb:
|
bb:
|
||||||
tail call void @free(i8* undef) nounwind
|
tail call void @free(ptr undef) nounwind
|
||||||
br label %bb
|
br label %bb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,36 +85,30 @@ bb:
|
||||||
%struct = type { i32 , i32 }
|
%struct = type { i32 , i32 }
|
||||||
|
|
||||||
; Test case inspired by PR48036.
|
; Test case inspired by PR48036.
|
||||||
define void @delete_field_after(%struct* %ptr) {
|
define void @delete_field_after(ptr %ptr) {
|
||||||
;
|
;
|
||||||
; CHECK-LABEL: @delete_field_after(
|
; CHECK-LABEL: @delete_field_after(
|
||||||
; CHECK-NEXT: [[PTR_F0:%.*]] = getelementptr [[STRUCT:%.*]], %struct* [[PTR:%.*]], i32 1
|
; CHECK-NEXT: [[PTR_F0:%.*]] = getelementptr [[STRUCT:%.*]], ptr [[PTR:%.*]], i32 1
|
||||||
; CHECK-NEXT: [[BC:%.*]] = bitcast %struct* [[PTR_F0]] to i8*
|
; CHECK-NEXT: [[PTR_F1:%.*]] = getelementptr [[STRUCT]], ptr [[PTR]], i32 0, i32 1
|
||||||
; CHECK-NEXT: [[PTR_F1:%.*]] = getelementptr [[STRUCT]], %struct* [[PTR]], i32 0, i32 1
|
; CHECK-NEXT: store i32 0, ptr [[PTR_F1]], align 4
|
||||||
; CHECK-NEXT: store i32 0, i32* [[PTR_F1]], align 4
|
; CHECK-NEXT: call void @free(ptr [[PTR_F0]])
|
||||||
; CHECK-NEXT: call void @free(i8* [[BC]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%ptr.f0 = getelementptr %struct, %struct* %ptr, i32 1
|
%ptr.f0 = getelementptr %struct, ptr %ptr, i32 1
|
||||||
%bc = bitcast %struct* %ptr.f0 to i8*
|
%ptr.f1 = getelementptr %struct, ptr %ptr, i32 0, i32 1
|
||||||
%ptr.f1 = getelementptr %struct, %struct* %ptr, i32 0, i32 1
|
store i32 0, ptr %ptr.f1
|
||||||
store i32 0, i32* %ptr.f1
|
call void @free(ptr %ptr.f0)
|
||||||
call void @free(i8* %bc)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Test case inspired by PR48036.
|
; Test case inspired by PR48036.
|
||||||
define void @delete_field_before(%struct* %ptr) {
|
define void @delete_field_before(ptr %ptr) {
|
||||||
; CHECK-LABEL: @delete_field_before(
|
; CHECK-LABEL: @delete_field_before(
|
||||||
; CHECK-NEXT: [[PTR_F0:%.*]] = getelementptr [[STRUCT:%.*]], %struct* [[PTR:%.*]], i32 0
|
; CHECK-NEXT: call void @free(ptr [[PTR:%.*]])
|
||||||
; CHECK-NEXT: [[BC:%.*]] = bitcast %struct* [[PTR_F0]] to i8*
|
|
||||||
; CHECK-NEXT: call void @free(i8* [[BC]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%ptr.f0 = getelementptr %struct, %struct* %ptr, i32 0
|
%ptr.f1 = getelementptr %struct, ptr %ptr, i32 1, i32 1
|
||||||
%bc = bitcast %struct* %ptr.f0 to i8*
|
store i32 0, ptr %ptr.f1
|
||||||
%ptr.f1 = getelementptr %struct, %struct* %ptr, i32 1, i32 1
|
call void @free(ptr %ptr)
|
||||||
store i32 0, i32* %ptr.f1
|
|
||||||
call void @free(i8* %bc)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@ define i32 @test_within_limit() !dbg !4 {
|
||||||
entry:
|
entry:
|
||||||
; The first store; later there is a second store to the same location,
|
; The first store; later there is a second store to the same location,
|
||||||
; so this store should be optimized away by DSE.
|
; so this store should be optimized away by DSE.
|
||||||
; CHECK-NOT: store i32 1, i32* @x, align 4
|
; CHECK-NOT: store i32 1, ptr @x, align 4
|
||||||
store i32 1, i32* @x, align 4
|
store i32 1, ptr @x, align 4
|
||||||
|
|
||||||
; Insert 98 dummy instructions between the two stores
|
; Insert 98 dummy instructions between the two stores
|
||||||
%0 = bitcast i32 0 to i32
|
%0 = bitcast i32 0 to i32
|
||||||
|
@ -119,8 +119,8 @@ entry:
|
||||||
; effect on the working of DSE in any way.
|
; effect on the working of DSE in any way.
|
||||||
call void @llvm.dbg.value(metadata i32 undef, metadata !10, metadata !DIExpression()), !dbg !DILocation(scope: !4)
|
call void @llvm.dbg.value(metadata i32 undef, metadata !10, metadata !DIExpression()), !dbg !DILocation(scope: !4)
|
||||||
|
|
||||||
; CHECK: store i32 -1, i32* @x, align 4
|
; CHECK: store i32 -1, ptr @x, align 4
|
||||||
store i32 -1, i32* @x, align 4
|
store i32 -1, ptr @x, align 4
|
||||||
ret i32 0
|
ret i32 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,8 +128,8 @@ entry:
|
||||||
define i32 @test_outside_limit() {
|
define i32 @test_outside_limit() {
|
||||||
entry:
|
entry:
|
||||||
; The first store; later there is a second store to the same location
|
; The first store; later there is a second store to the same location
|
||||||
; CHECK-NOT: store i32 1, i32* @x, align 4
|
; CHECK-NOT: store i32 1, ptr @x, align 4
|
||||||
store i32 1, i32* @x, align 4
|
store i32 1, ptr @x, align 4
|
||||||
|
|
||||||
; Insert 99 dummy instructions between the two stores; this is
|
; Insert 99 dummy instructions between the two stores; this is
|
||||||
; one too many instruction for the DSE to take place.
|
; one too many instruction for the DSE to take place.
|
||||||
|
@ -233,8 +233,8 @@ entry:
|
||||||
%97 = bitcast i32 0 to i32
|
%97 = bitcast i32 0 to i32
|
||||||
%98 = bitcast i32 0 to i32
|
%98 = bitcast i32 0 to i32
|
||||||
|
|
||||||
; CHECK: store i32 -1, i32* @x, align 4
|
; CHECK: store i32 -1, ptr @x, align 4
|
||||||
store i32 -1, i32* @x, align 4
|
store i32 -1, ptr @x, align 4
|
||||||
ret i32 0
|
ret i32 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,6 +255,6 @@ declare void @llvm.dbg.value(metadata, metadata, metadata)
|
||||||
!9 = !{!10}
|
!9 = !{!10}
|
||||||
!10 = !DILocalVariable(name: "x", scope: !4, type: !8)
|
!10 = !DILocalVariable(name: "x", scope: !4, type: !8)
|
||||||
!11 = !{i32 2, !"Dwarf Version", i32 4}
|
!11 = !{i32 2, !"Dwarf Version", i32 4}
|
||||||
!12 = !{i32* undef}
|
!12 = !{ptr undef}
|
||||||
|
|
||||||
!13 = !{i32 1, !"Debug Info Version", i32 3}
|
!13 = !{i32 1, !"Debug Info Version", i32 3}
|
||||||
|
|
|
@ -7,9 +7,9 @@ declare void @llvm.sideeffect()
|
||||||
; CHECK-LABEL: dse
|
; CHECK-LABEL: dse
|
||||||
; CHECK: store
|
; CHECK: store
|
||||||
; CHECK-NOT: store
|
; CHECK-NOT: store
|
||||||
define void @dse(float* %p) {
|
define void @dse(ptr %p) {
|
||||||
store float 0.0, float* %p
|
store float 0.0, ptr %p
|
||||||
call void @llvm.sideeffect()
|
call void @llvm.sideeffect()
|
||||||
store float 0.0, float* %p
|
store float 0.0, ptr %p
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,36 +2,36 @@
|
||||||
; Test to make sure llvm.invariant.start calls are not treated as clobbers.
|
; Test to make sure llvm.invariant.start calls are not treated as clobbers.
|
||||||
; RUN: opt < %s -basic-aa -dse -S | FileCheck %s
|
; RUN: opt < %s -basic-aa -dse -S | FileCheck %s
|
||||||
|
|
||||||
declare {}* @llvm.invariant.start.p0i8(i64, i8* nocapture) nounwind readonly
|
declare ptr @llvm.invariant.start.p0(i64, ptr nocapture) nounwind readonly
|
||||||
|
|
||||||
; We could remove either store here. The first store is dead in the
|
; We could remove either store here. The first store is dead in the
|
||||||
; conventional sense, because there is a later killing store. The second store
|
; conventional sense, because there is a later killing store. The second store
|
||||||
; is undefined behavior by the semantics of invariant.start, and as such
|
; is undefined behavior by the semantics of invariant.start, and as such
|
||||||
; unreachable.
|
; unreachable.
|
||||||
define void @test(i8 *%p) {
|
define void @test(ptr %p) {
|
||||||
; CHECK-LABEL: @test(
|
; CHECK-LABEL: @test(
|
||||||
; CHECK-NEXT: store i8 3, i8* [[P:%.*]], align 4
|
; CHECK-NEXT: store i8 3, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i8 1, i8* %p, align 4
|
store i8 1, ptr %p, align 4
|
||||||
%i = call {}* @llvm.invariant.start.p0i8(i64 1, i8* %p)
|
%i = call ptr @llvm.invariant.start.p0(i64 1, ptr %p)
|
||||||
store i8 3, i8* %p, align 4
|
store i8 3, ptr %p, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; FIXME: We should be able to remove the first store to p, even though p and q
|
; FIXME: We should be able to remove the first store to p, even though p and q
|
||||||
; may alias.
|
; may alias.
|
||||||
define void @test2(i8* %p, i8* %q) {
|
define void @test2(ptr %p, ptr %q) {
|
||||||
; CHECK-LABEL: @test2(
|
; CHECK-LABEL: @test2(
|
||||||
; CHECK-NEXT: store i8 1, i8* [[P:%.*]], align 4
|
; CHECK-NEXT: store i8 1, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: store i8 2, i8* [[Q:%.*]], align 4
|
; CHECK-NEXT: store i8 2, ptr [[Q:%.*]], align 4
|
||||||
; CHECK-NEXT: [[I:%.*]] = call {}* @llvm.invariant.start.p0i8(i64 1, i8* [[Q]])
|
; CHECK-NEXT: [[I:%.*]] = call ptr @llvm.invariant.start.p0(i64 1, ptr [[Q]])
|
||||||
; CHECK-NEXT: store i8 3, i8* [[P]], align 4
|
; CHECK-NEXT: store i8 3, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i8 1, i8* %p, align 4
|
store i8 1, ptr %p, align 4
|
||||||
store i8 2, i8* %q, align 4
|
store i8 2, ptr %q, align 4
|
||||||
%i = call {}* @llvm.invariant.start.p0i8(i64 1, i8* %q)
|
%i = call ptr @llvm.invariant.start.p0(i64 1, ptr %q)
|
||||||
store i8 3, i8* %p, align 4
|
store i8 3, ptr %p, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,65 +1,65 @@
|
||||||
; RUN: opt < %s -basic-aa -dse -S | FileCheck %s
|
; RUN: opt < %s -basic-aa -dse -S | FileCheck %s
|
||||||
|
|
||||||
; CHECK-LABEL: void @skipBarrier(i8* %ptr)
|
; CHECK-LABEL: void @skipBarrier(ptr %ptr)
|
||||||
define void @skipBarrier(i8* %ptr) {
|
define void @skipBarrier(ptr %ptr) {
|
||||||
; CHECK-NOT: store i8 42
|
; CHECK-NOT: store i8 42
|
||||||
store i8 42, i8* %ptr
|
store i8 42, ptr %ptr
|
||||||
; CHECK: %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
|
; CHECK: %ptr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr)
|
||||||
%ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
|
%ptr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr)
|
||||||
; CHECK: store i8 43
|
; CHECK: store i8 43
|
||||||
store i8 43, i8* %ptr2
|
store i8 43, ptr %ptr2
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK-LABEL: void @skip2Barriers(i8* %ptr)
|
; CHECK-LABEL: void @skip2Barriers(ptr %ptr)
|
||||||
define void @skip2Barriers(i8* %ptr) {
|
define void @skip2Barriers(ptr %ptr) {
|
||||||
; CHECK-NOT: store i8 42
|
; CHECK-NOT: store i8 42
|
||||||
store i8 42, i8* %ptr
|
store i8 42, ptr %ptr
|
||||||
; CHECK: %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
|
; CHECK: %ptr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr)
|
||||||
%ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
|
%ptr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr)
|
||||||
; CHECK-NOT: store i8 43
|
; CHECK-NOT: store i8 43
|
||||||
store i8 43, i8* %ptr2
|
store i8 43, ptr %ptr2
|
||||||
%ptr3 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr2)
|
%ptr3 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr2)
|
||||||
%ptr4 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr3)
|
%ptr4 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr3)
|
||||||
|
|
||||||
; CHECK: store i8 44
|
; CHECK: store i8 44
|
||||||
store i8 44, i8* %ptr4
|
store i8 44, ptr %ptr4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK-LABEL: void @skip3Barriers(i8* %ptr)
|
; CHECK-LABEL: void @skip3Barriers(ptr %ptr)
|
||||||
define void @skip3Barriers(i8* %ptr) {
|
define void @skip3Barriers(ptr %ptr) {
|
||||||
; CHECK-NOT: store i8 42
|
; CHECK-NOT: store i8 42
|
||||||
store i8 42, i8* %ptr
|
store i8 42, ptr %ptr
|
||||||
; CHECK: %ptr2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %ptr)
|
; CHECK: %ptr2 = call ptr @llvm.strip.invariant.group.p0(ptr %ptr)
|
||||||
%ptr2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %ptr)
|
%ptr2 = call ptr @llvm.strip.invariant.group.p0(ptr %ptr)
|
||||||
; CHECK-NOT: store i8 43
|
; CHECK-NOT: store i8 43
|
||||||
store i8 43, i8* %ptr2
|
store i8 43, ptr %ptr2
|
||||||
%ptr3 = call i8* @llvm.strip.invariant.group.p0i8(i8* %ptr2)
|
%ptr3 = call ptr @llvm.strip.invariant.group.p0(ptr %ptr2)
|
||||||
%ptr4 = call i8* @llvm.strip.invariant.group.p0i8(i8* %ptr3)
|
%ptr4 = call ptr @llvm.strip.invariant.group.p0(ptr %ptr3)
|
||||||
|
|
||||||
; CHECK: store i8 44
|
; CHECK: store i8 44
|
||||||
store i8 44, i8* %ptr4
|
store i8 44, ptr %ptr4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK-LABEL: void @skip4Barriers(i8* %ptr)
|
; CHECK-LABEL: void @skip4Barriers(ptr %ptr)
|
||||||
define void @skip4Barriers(i8* %ptr) {
|
define void @skip4Barriers(ptr %ptr) {
|
||||||
; CHECK-NOT: store i8 42
|
; CHECK-NOT: store i8 42
|
||||||
store i8 42, i8* %ptr
|
store i8 42, ptr %ptr
|
||||||
; CHECK: %ptr2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %ptr)
|
; CHECK: %ptr2 = call ptr @llvm.strip.invariant.group.p0(ptr %ptr)
|
||||||
%ptr2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %ptr)
|
%ptr2 = call ptr @llvm.strip.invariant.group.p0(ptr %ptr)
|
||||||
; CHECK-NOT: store i8 43
|
; CHECK-NOT: store i8 43
|
||||||
store i8 43, i8* %ptr2
|
store i8 43, ptr %ptr2
|
||||||
%ptr3 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr2)
|
%ptr3 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr2)
|
||||||
%ptr4 = call i8* @llvm.strip.invariant.group.p0i8(i8* %ptr3)
|
%ptr4 = call ptr @llvm.strip.invariant.group.p0(ptr %ptr3)
|
||||||
%ptr5 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr3)
|
%ptr5 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr3)
|
||||||
|
|
||||||
; CHECK: store i8 44
|
; CHECK: store i8 44
|
||||||
store i8 44, i8* %ptr5
|
store i8 44, ptr %ptr5
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
declare i8* @llvm.launder.invariant.group.p0i8(i8*)
|
declare ptr @llvm.launder.invariant.group.p0(ptr)
|
||||||
declare i8* @llvm.strip.invariant.group.p0i8(i8*)
|
declare ptr @llvm.strip.invariant.group.p0(ptr)
|
||||||
|
|
|
@ -3,114 +3,114 @@
|
||||||
|
|
||||||
; Tests for libcalls only available on Darwin platforms.
|
; Tests for libcalls only available on Darwin platforms.
|
||||||
|
|
||||||
declare void @memset_pattern4(i8*, i8*, i64)
|
declare void @memset_pattern4(ptr, ptr, i64)
|
||||||
declare void @memset_pattern8(i8*, i8*, i64)
|
declare void @memset_pattern8(ptr, ptr, i64)
|
||||||
declare void @memset_pattern16(i8*, i8*, i64)
|
declare void @memset_pattern16(ptr, ptr, i64)
|
||||||
|
|
||||||
define void @test_memset_pattern4_const_size(i8* noalias %a, i8* noalias %pattern) {
|
define void @test_memset_pattern4_const_size(ptr noalias %a, ptr noalias %pattern) {
|
||||||
; CHECK-LABEL: @test_memset_pattern4_const_size(
|
; CHECK-LABEL: @test_memset_pattern4_const_size(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[A_GEP_17:%.*]] = getelementptr i8, i8* [[A:%.*]], i32 17
|
; CHECK-NEXT: [[A_GEP_17:%.*]] = getelementptr i8, ptr [[A:%.*]], i32 17
|
||||||
; CHECK-NEXT: store i8 1, i8* [[A_GEP_17]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[A_GEP_17]], align 1
|
||||||
; CHECK-NEXT: call void @memset_pattern4(i8* [[A]], i8* [[PATTERN:%.*]], i64 17)
|
; CHECK-NEXT: call void @memset_pattern4(ptr [[A]], ptr [[PATTERN:%.*]], i64 17)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%a.gep.1 = getelementptr i8, i8* %a, i32 1
|
%a.gep.1 = getelementptr i8, ptr %a, i32 1
|
||||||
store i8 0, i8* %a.gep.1
|
store i8 0, ptr %a.gep.1
|
||||||
%a.gep.17 = getelementptr i8, i8* %a, i32 17
|
%a.gep.17 = getelementptr i8, ptr %a, i32 17
|
||||||
store i8 1, i8* %a.gep.17
|
store i8 1, ptr %a.gep.17
|
||||||
call void @memset_pattern4(i8* %a, i8* %pattern, i64 17)
|
call void @memset_pattern4(ptr %a, ptr %pattern, i64 17)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test_memset_pattern4_variable_size(i8* noalias %a, i8* noalias %pattern, i64 %n) {
|
define void @test_memset_pattern4_variable_size(ptr noalias %a, ptr noalias %pattern, i64 %n) {
|
||||||
; CHECK-LABEL: @test_memset_pattern4_variable_size(
|
; CHECK-LABEL: @test_memset_pattern4_variable_size(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[A_GEP_1:%.*]] = getelementptr i8, i8* [[A:%.*]], i32 1
|
; CHECK-NEXT: [[A_GEP_1:%.*]] = getelementptr i8, ptr [[A:%.*]], i32 1
|
||||||
; CHECK-NEXT: store i8 0, i8* [[A_GEP_1]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[A_GEP_1]], align 1
|
||||||
; CHECK-NEXT: [[A_GEP_17:%.*]] = getelementptr i8, i8* [[A]], i32 17
|
; CHECK-NEXT: [[A_GEP_17:%.*]] = getelementptr i8, ptr [[A]], i32 17
|
||||||
; CHECK-NEXT: store i8 1, i8* [[A_GEP_17]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[A_GEP_17]], align 1
|
||||||
; CHECK-NEXT: call void @memset_pattern4(i8* [[A]], i8* [[PATTERN:%.*]], i64 [[N:%.*]])
|
; CHECK-NEXT: call void @memset_pattern4(ptr [[A]], ptr [[PATTERN:%.*]], i64 [[N:%.*]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%a.gep.1 = getelementptr i8, i8* %a, i32 1
|
%a.gep.1 = getelementptr i8, ptr %a, i32 1
|
||||||
store i8 0, i8* %a.gep.1
|
store i8 0, ptr %a.gep.1
|
||||||
%a.gep.17 = getelementptr i8, i8* %a, i32 17
|
%a.gep.17 = getelementptr i8, ptr %a, i32 17
|
||||||
store i8 1, i8* %a.gep.17
|
store i8 1, ptr %a.gep.17
|
||||||
call void @memset_pattern4(i8* %a, i8* %pattern, i64 %n)
|
call void @memset_pattern4(ptr %a, ptr %pattern, i64 %n)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test_memset_pattern8_const_size(i8* noalias %a, i8* noalias %pattern) {
|
define void @test_memset_pattern8_const_size(ptr noalias %a, ptr noalias %pattern) {
|
||||||
; CHECK-LABEL: @test_memset_pattern8_const_size(
|
; CHECK-LABEL: @test_memset_pattern8_const_size(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[A_GEP_17:%.*]] = getelementptr i8, i8* [[A:%.*]], i32 17
|
; CHECK-NEXT: [[A_GEP_17:%.*]] = getelementptr i8, ptr [[A:%.*]], i32 17
|
||||||
; CHECK-NEXT: store i8 1, i8* [[A_GEP_17]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[A_GEP_17]], align 1
|
||||||
; CHECK-NEXT: call void @memset_pattern8(i8* [[A]], i8* [[PATTERN:%.*]], i64 17)
|
; CHECK-NEXT: call void @memset_pattern8(ptr [[A]], ptr [[PATTERN:%.*]], i64 17)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%a.gep.1 = getelementptr i8, i8* %a, i32 1
|
%a.gep.1 = getelementptr i8, ptr %a, i32 1
|
||||||
store i8 0, i8* %a.gep.1
|
store i8 0, ptr %a.gep.1
|
||||||
%a.gep.17 = getelementptr i8, i8* %a, i32 17
|
%a.gep.17 = getelementptr i8, ptr %a, i32 17
|
||||||
store i8 1, i8* %a.gep.17
|
store i8 1, ptr %a.gep.17
|
||||||
call void @memset_pattern8(i8* %a, i8* %pattern, i64 17)
|
call void @memset_pattern8(ptr %a, ptr %pattern, i64 17)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test_memset_pattern8_variable_size(i8* noalias %a, i8* noalias %pattern, i64 %n) {
|
define void @test_memset_pattern8_variable_size(ptr noalias %a, ptr noalias %pattern, i64 %n) {
|
||||||
; CHECK-LABEL: @test_memset_pattern8_variable_size(
|
; CHECK-LABEL: @test_memset_pattern8_variable_size(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[A_GEP_1:%.*]] = getelementptr i8, i8* [[A:%.*]], i32 1
|
; CHECK-NEXT: [[A_GEP_1:%.*]] = getelementptr i8, ptr [[A:%.*]], i32 1
|
||||||
; CHECK-NEXT: store i8 0, i8* [[A_GEP_1]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[A_GEP_1]], align 1
|
||||||
; CHECK-NEXT: [[A_GEP_17:%.*]] = getelementptr i8, i8* [[A]], i32 17
|
; CHECK-NEXT: [[A_GEP_17:%.*]] = getelementptr i8, ptr [[A]], i32 17
|
||||||
; CHECK-NEXT: store i8 1, i8* [[A_GEP_17]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[A_GEP_17]], align 1
|
||||||
; CHECK-NEXT: call void @memset_pattern8(i8* [[A]], i8* [[PATTERN:%.*]], i64 [[N:%.*]])
|
; CHECK-NEXT: call void @memset_pattern8(ptr [[A]], ptr [[PATTERN:%.*]], i64 [[N:%.*]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%a.gep.1 = getelementptr i8, i8* %a, i32 1
|
%a.gep.1 = getelementptr i8, ptr %a, i32 1
|
||||||
store i8 0, i8* %a.gep.1
|
store i8 0, ptr %a.gep.1
|
||||||
%a.gep.17 = getelementptr i8, i8* %a, i32 17
|
%a.gep.17 = getelementptr i8, ptr %a, i32 17
|
||||||
store i8 1, i8* %a.gep.17
|
store i8 1, ptr %a.gep.17
|
||||||
call void @memset_pattern8(i8* %a, i8* %pattern, i64 %n)
|
call void @memset_pattern8(ptr %a, ptr %pattern, i64 %n)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test_memset_pattern16_const_size(i8* noalias %a, i8* noalias %pattern) {
|
define void @test_memset_pattern16_const_size(ptr noalias %a, ptr noalias %pattern) {
|
||||||
; CHECK-LABEL: @test_memset_pattern16_const_size(
|
; CHECK-LABEL: @test_memset_pattern16_const_size(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[A_GEP_17:%.*]] = getelementptr i8, i8* [[A:%.*]], i32 17
|
; CHECK-NEXT: [[A_GEP_17:%.*]] = getelementptr i8, ptr [[A:%.*]], i32 17
|
||||||
; CHECK-NEXT: store i8 1, i8* [[A_GEP_17]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[A_GEP_17]], align 1
|
||||||
; CHECK-NEXT: call void @memset_pattern16(i8* [[A]], i8* [[PATTERN:%.*]], i64 17)
|
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr [[PATTERN:%.*]], i64 17)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%a.gep.1 = getelementptr i8, i8* %a, i32 1
|
%a.gep.1 = getelementptr i8, ptr %a, i32 1
|
||||||
store i8 0, i8* %a.gep.1
|
store i8 0, ptr %a.gep.1
|
||||||
%a.gep.17 = getelementptr i8, i8* %a, i32 17
|
%a.gep.17 = getelementptr i8, ptr %a, i32 17
|
||||||
store i8 1, i8* %a.gep.17
|
store i8 1, ptr %a.gep.17
|
||||||
call void @memset_pattern16(i8* %a, i8* %pattern, i64 17)
|
call void @memset_pattern16(ptr %a, ptr %pattern, i64 17)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test_memset_pattern16_variable_size(i8* noalias %a, i8* noalias %pattern, i64 %n) {
|
define void @test_memset_pattern16_variable_size(ptr noalias %a, ptr noalias %pattern, i64 %n) {
|
||||||
; CHECK-LABEL: @test_memset_pattern16_variable_size(
|
; CHECK-LABEL: @test_memset_pattern16_variable_size(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[A_GEP_1:%.*]] = getelementptr i8, i8* [[A:%.*]], i32 1
|
; CHECK-NEXT: [[A_GEP_1:%.*]] = getelementptr i8, ptr [[A:%.*]], i32 1
|
||||||
; CHECK-NEXT: store i8 0, i8* [[A_GEP_1]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[A_GEP_1]], align 1
|
||||||
; CHECK-NEXT: [[A_GEP_17:%.*]] = getelementptr i8, i8* [[A]], i32 17
|
; CHECK-NEXT: [[A_GEP_17:%.*]] = getelementptr i8, ptr [[A]], i32 17
|
||||||
; CHECK-NEXT: store i8 1, i8* [[A_GEP_17]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[A_GEP_17]], align 1
|
||||||
; CHECK-NEXT: call void @memset_pattern16(i8* [[A]], i8* [[PATTERN:%.*]], i64 [[N:%.*]])
|
; CHECK-NEXT: call void @memset_pattern16(ptr [[A]], ptr [[PATTERN:%.*]], i64 [[N:%.*]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%a.gep.1 = getelementptr i8, i8* %a, i32 1
|
%a.gep.1 = getelementptr i8, ptr %a, i32 1
|
||||||
store i8 0, i8* %a.gep.1
|
store i8 0, ptr %a.gep.1
|
||||||
%a.gep.17 = getelementptr i8, i8* %a, i32 17
|
%a.gep.17 = getelementptr i8, ptr %a, i32 17
|
||||||
store i8 1, i8* %a.gep.17
|
store i8 1, ptr %a.gep.17
|
||||||
call void @memset_pattern16(i8* %a, i8* %pattern, i64 %n)
|
call void @memset_pattern16(ptr %a, ptr %pattern, i64 %n)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,616 +4,578 @@
|
||||||
|
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
||||||
declare i8* @strcpy(i8* %dest, i8* %src) nounwind
|
declare ptr @strcpy(ptr %dest, ptr %src) nounwind
|
||||||
define void @test1(i8* %src) {
|
define void @test1(ptr %src) {
|
||||||
; CHECK-LABEL: @test1(
|
; CHECK-LABEL: @test1(
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%B = alloca [16 x i8]
|
%B = alloca [16 x i8]
|
||||||
%dest = getelementptr inbounds [16 x i8], [16 x i8]* %B, i64 0, i64 0
|
%call = call ptr @strcpy(ptr %B, ptr %src)
|
||||||
%call = call i8* @strcpy(i8* %dest, i8* %src)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @strcpy_reads_after(i8* noalias %dest, i8* %src) {
|
define void @strcpy_reads_after(ptr noalias %dest, ptr %src) {
|
||||||
; CHECK-LABEL: @strcpy_reads_after(
|
; CHECK-LABEL: @strcpy_reads_after(
|
||||||
; CHECK-NEXT: [[SRC_2:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 1
|
; CHECK-NEXT: [[SRC_2:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 1
|
||||||
; CHECK-NEXT: store i8 99, i8* [[SRC_2]], align 1
|
; CHECK-NEXT: store i8 99, ptr [[SRC_2]], align 1
|
||||||
; CHECK-NEXT: [[SRC_1:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i64 1
|
; CHECK-NEXT: [[SRC_1:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 1
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = call i8* @strcpy(i8* [[DEST:%.*]], i8* [[SRC_1]])
|
; CHECK-NEXT: [[CALL:%.*]] = call ptr @strcpy(ptr [[DEST:%.*]], ptr [[SRC_1]])
|
||||||
; CHECK-NEXT: store i8 2, i8* [[SRC]], align 1
|
; CHECK-NEXT: store i8 2, ptr [[SRC]], align 1
|
||||||
; CHECK-NEXT: store i8 2, i8* [[SRC_2]], align 1
|
; CHECK-NEXT: store i8 2, ptr [[SRC_2]], align 1
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%src.2 = getelementptr inbounds i8, i8* %src, i64 1
|
%src.2 = getelementptr inbounds i8, ptr %src, i64 1
|
||||||
store i8 1, i8* %src
|
store i8 1, ptr %src
|
||||||
store i8 99, i8* %src.2
|
store i8 99, ptr %src.2
|
||||||
%src.1 = getelementptr inbounds i8, i8* %src, i64 1
|
%src.1 = getelementptr inbounds i8, ptr %src, i64 1
|
||||||
%call = call i8* @strcpy(i8* %dest, i8* %src.1)
|
%call = call ptr @strcpy(ptr %dest, ptr %src.1)
|
||||||
store i8 2, i8* %src
|
store i8 2, ptr %src
|
||||||
store i8 2, i8* %src.2
|
store i8 2, ptr %src.2
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i8* @strncpy(i8* %dest, i8* %src, i64 %n) nounwind
|
declare ptr @strncpy(ptr %dest, ptr %src, i64 %n) nounwind
|
||||||
define void @test2(i8* %src) {
|
define void @test2(ptr %src) {
|
||||||
; CHECK-LABEL: @test2(
|
; CHECK-LABEL: @test2(
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%B = alloca [16 x i8]
|
%B = alloca [16 x i8]
|
||||||
%dest = getelementptr inbounds [16 x i8], [16 x i8]* %B, i64 0, i64 0
|
%call = call ptr @strncpy(ptr %B, ptr %src, i64 12)
|
||||||
%call = call i8* @strncpy(i8* %dest, i8* %src, i64 12)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i8* @strcat(i8* %dest, i8* %src) nounwind
|
declare ptr @strcat(ptr %B, ptr %src) nounwind
|
||||||
define void @test3(i8* %src) {
|
define void @test3(ptr %src) {
|
||||||
; CHECK-LABEL: @test3(
|
; CHECK-LABEL: @test3(
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%B = alloca [16 x i8]
|
%B = alloca [16 x i8]
|
||||||
%dest = getelementptr inbounds [16 x i8], [16 x i8]* %B, i64 0, i64 0
|
%call = call ptr @strcat(ptr %B, ptr %src)
|
||||||
%call = call i8* @strcat(i8* %dest, i8* %src)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test_strcat_with_lifetime(i8* %src) {
|
define void @test_strcat_with_lifetime(ptr %src) {
|
||||||
; CHECK-LABEL: @test_strcat_with_lifetime(
|
; CHECK-LABEL: @test_strcat_with_lifetime(
|
||||||
; CHECK-NEXT: [[B:%.*]] = alloca [16 x i8], align 1
|
; CHECK-NEXT: [[B:%.*]] = alloca [16 x i8], align 1
|
||||||
; CHECK-NEXT: [[B_CAST:%.*]] = bitcast [16 x i8]* [[B]] to i8*
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[B]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull [[B_CAST]])
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[B]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull [[B_CAST]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%B = alloca [16 x i8]
|
%B = alloca [16 x i8]
|
||||||
%B.cast = bitcast [16 x i8]* %B to i8*
|
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %B)
|
||||||
call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull %B.cast)
|
%call = call ptr @strcat(ptr %B, ptr %src)
|
||||||
%dest = getelementptr inbounds [16 x i8], [16 x i8]* %B, i64 0, i64 0
|
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %B)
|
||||||
%call = call i8* @strcat(i8* %dest, i8* %src)
|
|
||||||
call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull %B.cast)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test_strcat_with_lifetime_nonlocal(i8* %dest, i8* %src) {
|
define void @test_strcat_with_lifetime_nonlocal(ptr %dest, ptr %src) {
|
||||||
; CHECK-LABEL: @test_strcat_with_lifetime_nonlocal(
|
; CHECK-LABEL: @test_strcat_with_lifetime_nonlocal(
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull [[DEST:%.*]])
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[DEST:%.*]])
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = call i8* @strcat(i8* [[DEST]], i8* [[SRC:%.*]])
|
; CHECK-NEXT: [[CALL:%.*]] = call ptr @strcat(ptr [[DEST]], ptr [[SRC:%.*]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull [[DEST]])
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[DEST]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull %dest)
|
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %dest)
|
||||||
%call = call i8* @strcat(i8* %dest, i8* %src)
|
%call = call ptr @strcat(ptr %dest, ptr %src)
|
||||||
call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull %dest)
|
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %dest)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i8* @strncat(i8* %dest, i8* %src, i64 %n) nounwind
|
declare ptr @strncat(ptr %dest, ptr %src, i64 %n) nounwind
|
||||||
define void @test4(i8* %src) {
|
define void @test4(ptr %src) {
|
||||||
; CHECK-LABEL: @test4(
|
; CHECK-LABEL: @test4(
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%B = alloca [16 x i8]
|
%B = alloca [16 x i8]
|
||||||
%dest = getelementptr inbounds [16 x i8], [16 x i8]* %B, i64 0, i64 0
|
%call = call ptr @strncat(ptr %B, ptr %src, i64 12)
|
||||||
%call = call i8* @strncat(i8* %dest, i8* %src, i64 12)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test5(i8* nocapture %src) {
|
define void @test5(ptr nocapture %src) {
|
||||||
; CHECK-LABEL: @test5(
|
; CHECK-LABEL: @test5(
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%dest = alloca [100 x i8], align 16
|
%dest = alloca [100 x i8], align 16
|
||||||
%arraydecay = getelementptr inbounds [100 x i8], [100 x i8]* %dest, i64 0, i64 0
|
%call = call ptr @strcpy(ptr %dest, ptr %src)
|
||||||
%call = call i8* @strcpy(i8* %arraydecay, i8* %src)
|
%arrayidx = getelementptr inbounds i8, ptr %call, i64 10
|
||||||
%arrayidx = getelementptr inbounds i8, i8* %call, i64 10
|
store i8 97, ptr %arrayidx, align 1
|
||||||
store i8 97, i8* %arrayidx, align 1
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @user(i8* %p)
|
declare void @user(ptr %p)
|
||||||
define void @test6(i8* %src) {
|
define void @test6(ptr %src) {
|
||||||
; CHECK-LABEL: @test6(
|
; CHECK-LABEL: @test6(
|
||||||
; CHECK-NEXT: [[B:%.*]] = alloca [16 x i8], align 1
|
; CHECK-NEXT: [[B:%.*]] = alloca [16 x i8], align 1
|
||||||
; CHECK-NEXT: [[DEST:%.*]] = getelementptr inbounds [16 x i8], [16 x i8]* [[B]], i64 0, i64 0
|
; CHECK-NEXT: [[CALL:%.*]] = call ptr @strcpy(ptr [[B]], ptr [[SRC:%.*]])
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = call i8* @strcpy(i8* [[DEST]], i8* [[SRC:%.*]])
|
; CHECK-NEXT: call void @user(ptr [[B]])
|
||||||
; CHECK-NEXT: call void @user(i8* [[DEST]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%B = alloca [16 x i8]
|
%B = alloca [16 x i8]
|
||||||
%dest = getelementptr inbounds [16 x i8], [16 x i8]* %B, i64 0, i64 0
|
%call = call ptr @strcpy(ptr %B, ptr %src)
|
||||||
%call = call i8* @strcpy(i8* %dest, i8* %src)
|
call void @user(ptr %B)
|
||||||
call void @user(i8* %dest)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i32 @memcmp(i8*, i8*, i64)
|
declare i32 @memcmp(ptr, ptr, i64)
|
||||||
|
|
||||||
define i32 @test_memcmp_const_size(i8* noalias %foo) {
|
define i32 @test_memcmp_const_size(ptr noalias %foo) {
|
||||||
; CHECK-LABEL: @test_memcmp_const_size(
|
; CHECK-LABEL: @test_memcmp_const_size(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
|
; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
|
||||||
; CHECK-NEXT: [[STACK_PTR:%.*]] = bitcast [10 x i8]* [[STACK]] to i8*
|
; CHECK-NEXT: store i8 49, ptr [[STACK]], align 1
|
||||||
; CHECK-NEXT: store i8 49, i8* [[STACK_PTR]], align 1
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, ptr [[STACK]], i64 1
|
||||||
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 1
|
; CHECK-NEXT: store i8 50, ptr [[GEP_1]], align 1
|
||||||
; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @memcmp(ptr nonnull dereferenceable(2) [[FOO:%.*]], ptr nonnull dereferenceable(2) [[STACK]], i64 2)
|
||||||
; CHECK-NEXT: [[RES:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(2) [[FOO:%.*]], i8* nonnull dereferenceable(2) [[STACK_PTR]], i64 2)
|
|
||||||
; CHECK-NEXT: ret i32 [[RES]]
|
; CHECK-NEXT: ret i32 [[RES]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%stack = alloca [10 x i8]
|
%stack = alloca [10 x i8]
|
||||||
%stack.ptr = bitcast [10 x i8]* %stack to i8*
|
store i8 49, ptr %stack, align 1
|
||||||
store i8 49, i8* %stack.ptr, align 1
|
%gep.1 = getelementptr i8, ptr %stack, i64 1
|
||||||
%gep.1 = getelementptr i8, i8* %stack.ptr, i64 1
|
store i8 50, ptr %gep.1, align 1
|
||||||
store i8 50, i8* %gep.1, align 1
|
%gep.2 = getelementptr i8, ptr %stack, i64 2
|
||||||
%gep.2 = getelementptr i8, i8* %stack.ptr, i64 2
|
store i8 51, ptr %gep.2, align 1
|
||||||
store i8 51, i8* %gep.2, align 1
|
%gep.3 = getelementptr i8, ptr %stack, i64 3
|
||||||
%gep.3 = getelementptr i8, i8* %stack.ptr, i64 3
|
store i8 52, ptr %gep.3, align 1
|
||||||
store i8 52, i8* %gep.3, align 1
|
%res = call i32 @memcmp(ptr nonnull dereferenceable(2) %foo, ptr nonnull dereferenceable(2) %stack, i64 2)
|
||||||
%res = call i32 @memcmp(i8* nonnull dereferenceable(2) %foo, i8* nonnull dereferenceable(2) %stack.ptr, i64 2)
|
|
||||||
ret i32 %res
|
ret i32 %res
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test_memcmp_variable_size(i8* noalias %foo, i64 %n) {
|
define i32 @test_memcmp_variable_size(ptr noalias %foo, i64 %n) {
|
||||||
; CHECK-LABEL: @test_memcmp_variable_size(
|
; CHECK-LABEL: @test_memcmp_variable_size(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
|
; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
|
||||||
; CHECK-NEXT: [[STACK_PTR:%.*]] = bitcast [10 x i8]* [[STACK]] to i8*
|
; CHECK-NEXT: store i8 49, ptr [[STACK]], align 1
|
||||||
; CHECK-NEXT: store i8 49, i8* [[STACK_PTR]], align 1
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, ptr [[STACK]], i64 1
|
||||||
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 1
|
; CHECK-NEXT: store i8 50, ptr [[GEP_1]], align 1
|
||||||
; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1
|
; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr i8, ptr [[STACK]], i64 2
|
||||||
; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 2
|
; CHECK-NEXT: store i8 51, ptr [[GEP_2]], align 1
|
||||||
; CHECK-NEXT: store i8 51, i8* [[GEP_2]], align 1
|
; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr i8, ptr [[STACK]], i64 3
|
||||||
; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 3
|
; CHECK-NEXT: store i8 52, ptr [[GEP_3]], align 1
|
||||||
; CHECK-NEXT: store i8 52, i8* [[GEP_3]], align 1
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @memcmp(ptr nonnull [[FOO:%.*]], ptr nonnull [[STACK]], i64 [[N:%.*]])
|
||||||
; CHECK-NEXT: [[RES:%.*]] = call i32 @memcmp(i8* nonnull [[FOO:%.*]], i8* nonnull [[STACK_PTR]], i64 [[N:%.*]])
|
|
||||||
; CHECK-NEXT: ret i32 [[RES]]
|
; CHECK-NEXT: ret i32 [[RES]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%stack = alloca [10 x i8]
|
%stack = alloca [10 x i8]
|
||||||
%stack.ptr = bitcast [10 x i8]* %stack to i8*
|
store i8 49, ptr %stack, align 1
|
||||||
store i8 49, i8* %stack.ptr, align 1
|
%gep.1 = getelementptr i8, ptr %stack, i64 1
|
||||||
%gep.1 = getelementptr i8, i8* %stack.ptr, i64 1
|
store i8 50, ptr %gep.1, align 1
|
||||||
store i8 50, i8* %gep.1, align 1
|
%gep.2 = getelementptr i8, ptr %stack, i64 2
|
||||||
%gep.2 = getelementptr i8, i8* %stack.ptr, i64 2
|
store i8 51, ptr %gep.2, align 1
|
||||||
store i8 51, i8* %gep.2, align 1
|
%gep.3 = getelementptr i8, ptr %stack, i64 3
|
||||||
%gep.3 = getelementptr i8, i8* %stack.ptr, i64 3
|
store i8 52, ptr %gep.3, align 1
|
||||||
store i8 52, i8* %gep.3, align 1
|
%res = call i32 @memcmp(ptr nonnull %foo, ptr nonnull %stack, i64 %n)
|
||||||
%res = call i32 @memcmp(i8* nonnull %foo, i8* nonnull %stack.ptr, i64 %n)
|
|
||||||
ret i32 %res
|
ret i32 %res
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i32 @bcmp(i8*, i8*, i64)
|
declare i32 @bcmp(ptr, ptr, i64)
|
||||||
|
|
||||||
define i1 @test_bcmp_const_size(i8* noalias %foo) {
|
define i1 @test_bcmp_const_size(ptr noalias %foo) {
|
||||||
; CHECK-LABEL: @test_bcmp_const_size(
|
; CHECK-LABEL: @test_bcmp_const_size(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
|
; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
|
||||||
; CHECK-NEXT: [[STACK_PTR:%.*]] = bitcast [10 x i8]* [[STACK]] to i8*
|
; CHECK-NEXT: store i8 49, ptr [[STACK]], align 1
|
||||||
; CHECK-NEXT: store i8 49, i8* [[STACK_PTR]], align 1
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, ptr [[STACK]], i64 1
|
||||||
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 1
|
; CHECK-NEXT: store i8 50, ptr [[GEP_1]], align 1
|
||||||
; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @bcmp(ptr nonnull dereferenceable(2) [[FOO:%.*]], ptr nonnull dereferenceable(2) [[STACK]], i64 2)
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @bcmp(i8* nonnull dereferenceable(2) [[FOO:%.*]], i8* nonnull dereferenceable(2) [[STACK_PTR]], i64 2)
|
|
||||||
; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[CALL]], 0
|
; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[CALL]], 0
|
||||||
; CHECK-NEXT: ret i1 [[RES]]
|
; CHECK-NEXT: ret i1 [[RES]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%stack = alloca [10 x i8]
|
%stack = alloca [10 x i8]
|
||||||
%stack.ptr = bitcast [10 x i8]* %stack to i8*
|
store i8 49, ptr %stack, align 1
|
||||||
store i8 49, i8* %stack.ptr, align 1
|
%gep.1 = getelementptr i8, ptr %stack, i64 1
|
||||||
%gep.1 = getelementptr i8, i8* %stack.ptr, i64 1
|
store i8 50, ptr %gep.1, align 1
|
||||||
store i8 50, i8* %gep.1, align 1
|
%gep.2 = getelementptr i8, ptr %stack, i64 2
|
||||||
%gep.2 = getelementptr i8, i8* %stack.ptr, i64 2
|
store i8 51, ptr %gep.2, align 1
|
||||||
store i8 51, i8* %gep.2, align 1
|
%gep.3 = getelementptr i8, ptr %stack, i64 3
|
||||||
%gep.3 = getelementptr i8, i8* %stack.ptr, i64 3
|
store i8 52, ptr %gep.3, align 1
|
||||||
store i8 52, i8* %gep.3, align 1
|
%call = call i32 @bcmp(ptr nonnull dereferenceable(2) %foo, ptr nonnull dereferenceable(2) %stack, i64 2)
|
||||||
%call = call i32 @bcmp(i8* nonnull dereferenceable(2) %foo, i8* nonnull dereferenceable(2) %stack.ptr, i64 2)
|
|
||||||
%res = icmp eq i32 %call, 0
|
%res = icmp eq i32 %call, 0
|
||||||
ret i1 %res
|
ret i1 %res
|
||||||
}
|
}
|
||||||
|
|
||||||
define i1 @test_bcmp_variable_size(i8* noalias %foo, i64 %n) {
|
define i1 @test_bcmp_variable_size(ptr noalias %foo, i64 %n) {
|
||||||
; CHECK-LABEL: @test_bcmp_variable_size(
|
; CHECK-LABEL: @test_bcmp_variable_size(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
|
; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
|
||||||
; CHECK-NEXT: [[STACK_PTR:%.*]] = bitcast [10 x i8]* [[STACK]] to i8*
|
; CHECK-NEXT: store i8 49, ptr [[STACK]], align 1
|
||||||
; CHECK-NEXT: store i8 49, i8* [[STACK_PTR]], align 1
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, ptr [[STACK]], i64 1
|
||||||
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 1
|
; CHECK-NEXT: store i8 50, ptr [[GEP_1]], align 1
|
||||||
; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1
|
; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr i8, ptr [[STACK]], i64 2
|
||||||
; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 2
|
; CHECK-NEXT: store i8 51, ptr [[GEP_2]], align 1
|
||||||
; CHECK-NEXT: store i8 51, i8* [[GEP_2]], align 1
|
; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr i8, ptr [[STACK]], i64 3
|
||||||
; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 3
|
; CHECK-NEXT: store i8 52, ptr [[GEP_3]], align 1
|
||||||
; CHECK-NEXT: store i8 52, i8* [[GEP_3]], align 1
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @bcmp(ptr nonnull [[FOO:%.*]], ptr nonnull [[STACK]], i64 [[N:%.*]])
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @bcmp(i8* nonnull [[FOO:%.*]], i8* nonnull [[STACK_PTR]], i64 [[N:%.*]])
|
|
||||||
; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[CALL]], 0
|
; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[CALL]], 0
|
||||||
; CHECK-NEXT: ret i1 [[RES]]
|
; CHECK-NEXT: ret i1 [[RES]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%stack = alloca [10 x i8]
|
%stack = alloca [10 x i8]
|
||||||
%stack.ptr = bitcast [10 x i8]* %stack to i8*
|
store i8 49, ptr %stack, align 1
|
||||||
store i8 49, i8* %stack.ptr, align 1
|
%gep.1 = getelementptr i8, ptr %stack, i64 1
|
||||||
%gep.1 = getelementptr i8, i8* %stack.ptr, i64 1
|
store i8 50, ptr %gep.1, align 1
|
||||||
store i8 50, i8* %gep.1, align 1
|
%gep.2 = getelementptr i8, ptr %stack, i64 2
|
||||||
%gep.2 = getelementptr i8, i8* %stack.ptr, i64 2
|
store i8 51, ptr %gep.2, align 1
|
||||||
store i8 51, i8* %gep.2, align 1
|
%gep.3 = getelementptr i8, ptr %stack, i64 3
|
||||||
%gep.3 = getelementptr i8, i8* %stack.ptr, i64 3
|
store i8 52, ptr %gep.3, align 1
|
||||||
store i8 52, i8* %gep.3, align 1
|
%call = call i32 @bcmp(ptr nonnull %foo, ptr nonnull %stack, i64 %n)
|
||||||
%call = call i32 @bcmp(i8* nonnull %foo, i8* nonnull %stack.ptr, i64 %n)
|
|
||||||
%res = icmp eq i32 %call, 0
|
%res = icmp eq i32 %call, 0
|
||||||
ret i1 %res
|
ret i1 %res
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i8* @memchr(i8*, i32, i64)
|
declare ptr @memchr(ptr, i32, i64)
|
||||||
|
|
||||||
define i8* @test_memchr_const_size() {
|
define ptr @test_memchr_const_size() {
|
||||||
; CHECK-LABEL: @test_memchr_const_size(
|
; CHECK-LABEL: @test_memchr_const_size(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
|
; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
|
||||||
; CHECK-NEXT: [[STACK_PTR:%.*]] = bitcast [10 x i8]* [[STACK]] to i8*
|
; CHECK-NEXT: store i8 49, ptr [[STACK]], align 1
|
||||||
; CHECK-NEXT: store i8 49, i8* [[STACK_PTR]], align 1
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, ptr [[STACK]], i64 1
|
||||||
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 1
|
; CHECK-NEXT: store i8 50, ptr [[GEP_1]], align 1
|
||||||
; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1
|
; CHECK-NEXT: [[CALL:%.*]] = call ptr @memchr(ptr [[STACK]], i32 42, i64 2)
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = call i8* @memchr(i8* [[STACK_PTR]], i32 42, i64 2)
|
; CHECK-NEXT: ret ptr [[CALL]]
|
||||||
; CHECK-NEXT: ret i8* [[CALL]]
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%stack = alloca [10 x i8]
|
%stack = alloca [10 x i8]
|
||||||
%stack.ptr = bitcast [10 x i8]* %stack to i8*
|
store i8 49, ptr %stack, align 1
|
||||||
store i8 49, i8* %stack.ptr, align 1
|
%gep.1 = getelementptr i8, ptr %stack, i64 1
|
||||||
%gep.1 = getelementptr i8, i8* %stack.ptr, i64 1
|
store i8 50, ptr %gep.1, align 1
|
||||||
store i8 50, i8* %gep.1, align 1
|
%gep.2 = getelementptr i8, ptr %stack, i64 2
|
||||||
%gep.2 = getelementptr i8, i8* %stack.ptr, i64 2
|
store i8 51, ptr %gep.2, align 1
|
||||||
store i8 51, i8* %gep.2, align 1
|
%gep.3 = getelementptr i8, ptr %stack, i64 3
|
||||||
%gep.3 = getelementptr i8, i8* %stack.ptr, i64 3
|
store i8 52, ptr %gep.3, align 1
|
||||||
store i8 52, i8* %gep.3, align 1
|
%call = call ptr @memchr(ptr %stack, i32 42, i64 2)
|
||||||
%call = call i8* @memchr(i8* %stack.ptr, i32 42, i64 2)
|
ret ptr %call
|
||||||
ret i8* %call
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define i8* @test_memchr_variable_size(i64 %n) {
|
define ptr @test_memchr_variable_size(i64 %n) {
|
||||||
; CHECK-LABEL: @test_memchr_variable_size(
|
; CHECK-LABEL: @test_memchr_variable_size(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
|
; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
|
||||||
; CHECK-NEXT: [[STACK_PTR:%.*]] = bitcast [10 x i8]* [[STACK]] to i8*
|
; CHECK-NEXT: store i8 49, ptr [[STACK]], align 1
|
||||||
; CHECK-NEXT: store i8 49, i8* [[STACK_PTR]], align 1
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, ptr [[STACK]], i64 1
|
||||||
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 1
|
; CHECK-NEXT: store i8 50, ptr [[GEP_1]], align 1
|
||||||
; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1
|
; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr i8, ptr [[STACK]], i64 2
|
||||||
; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 2
|
; CHECK-NEXT: store i8 51, ptr [[GEP_2]], align 1
|
||||||
; CHECK-NEXT: store i8 51, i8* [[GEP_2]], align 1
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[STACK]], i64 4
|
||||||
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 4
|
; CHECK-NEXT: store i8 52, ptr [[GEP]], align 1
|
||||||
; CHECK-NEXT: store i8 52, i8* [[GEP]], align 1
|
; CHECK-NEXT: [[CALL:%.*]] = call ptr @memchr(ptr [[STACK]], i32 42, i64 [[N:%.*]])
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = call i8* @memchr(i8* [[STACK_PTR]], i32 42, i64 [[N:%.*]])
|
; CHECK-NEXT: ret ptr [[CALL]]
|
||||||
; CHECK-NEXT: ret i8* [[CALL]]
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%stack = alloca [10 x i8]
|
%stack = alloca [10 x i8]
|
||||||
%stack.ptr = bitcast [10 x i8]* %stack to i8*
|
store i8 49, ptr %stack, align 1
|
||||||
store i8 49, i8* %stack.ptr, align 1
|
%gep.1 = getelementptr i8, ptr %stack, i64 1
|
||||||
%gep.1 = getelementptr i8, i8* %stack.ptr, i64 1
|
store i8 50, ptr %gep.1, align 1
|
||||||
store i8 50, i8* %gep.1, align 1
|
%gep.2 = getelementptr i8, ptr %stack, i64 2
|
||||||
%gep.2 = getelementptr i8, i8* %stack.ptr, i64 2
|
store i8 51, ptr %gep.2, align 1
|
||||||
store i8 51, i8* %gep.2, align 1
|
%gep = getelementptr i8, ptr %stack, i64 4
|
||||||
%gep = getelementptr i8, i8* %stack.ptr, i64 4
|
store i8 52, ptr %gep, align 1
|
||||||
store i8 52, i8* %gep, align 1
|
%call = call ptr @memchr(ptr %stack, i32 42, i64 %n)
|
||||||
%call = call i8* @memchr(i8* %stack.ptr, i32 42, i64 %n)
|
ret ptr %call
|
||||||
ret i8* %call
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i8* @memccpy(i8*, i8*, i32, i64)
|
declare ptr @memccpy(ptr, ptr, i32, i64)
|
||||||
|
|
||||||
define i8* @test_memccpy_const_size(i8* %foo) {
|
define ptr @test_memccpy_const_size(ptr %foo) {
|
||||||
; CHECK-LABEL: @test_memccpy_const_size(
|
; CHECK-LABEL: @test_memccpy_const_size(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
|
; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
|
||||||
; CHECK-NEXT: [[STACK_PTR:%.*]] = bitcast [10 x i8]* [[STACK]] to i8*
|
; CHECK-NEXT: store i8 49, ptr [[STACK]], align 1
|
||||||
; CHECK-NEXT: store i8 49, i8* [[STACK_PTR]], align 1
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, ptr [[STACK]], i64 1
|
||||||
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 1
|
; CHECK-NEXT: store i8 50, ptr [[GEP_1]], align 1
|
||||||
; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1
|
; CHECK-NEXT: [[RES:%.*]] = call ptr @memccpy(ptr [[FOO:%.*]], ptr [[STACK]], i32 42, i64 2)
|
||||||
; CHECK-NEXT: [[RES:%.*]] = call i8* @memccpy(i8* [[FOO:%.*]], i8* [[STACK_PTR]], i32 42, i64 2)
|
; CHECK-NEXT: ret ptr [[RES]]
|
||||||
; CHECK-NEXT: ret i8* [[RES]]
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%stack = alloca [10 x i8]
|
%stack = alloca [10 x i8]
|
||||||
%stack.ptr = bitcast [10 x i8]* %stack to i8*
|
store i8 49, ptr %stack, align 1
|
||||||
store i8 49, i8* %stack.ptr, align 1
|
%gep.1 = getelementptr i8, ptr %stack, i64 1
|
||||||
%gep.1 = getelementptr i8, i8* %stack.ptr, i64 1
|
store i8 50, ptr %gep.1, align 1
|
||||||
store i8 50, i8* %gep.1, align 1
|
%gep.2 = getelementptr i8, ptr %stack, i64 2
|
||||||
%gep.2 = getelementptr i8, i8* %stack.ptr, i64 2
|
store i8 51, ptr %gep.2, align 1
|
||||||
store i8 51, i8* %gep.2, align 1
|
%gep.3 = getelementptr i8, ptr %stack, i64 3
|
||||||
%gep.3 = getelementptr i8, i8* %stack.ptr, i64 3
|
store i8 52, ptr %gep.3, align 1
|
||||||
store i8 52, i8* %gep.3, align 1
|
%res = call ptr @memccpy(ptr %foo, ptr %stack, i32 42, i64 2)
|
||||||
%res = call i8* @memccpy(i8* %foo, i8* %stack.ptr, i32 42, i64 2)
|
ret ptr %res
|
||||||
ret i8* %res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define i8* @test_memccpy_variable_size(i8* %foo, i64 %n) {
|
define ptr @test_memccpy_variable_size(ptr %foo, i64 %n) {
|
||||||
; CHECK-LABEL: @test_memccpy_variable_size(
|
; CHECK-LABEL: @test_memccpy_variable_size(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
|
; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
|
||||||
; CHECK-NEXT: [[STACK_PTR:%.*]] = bitcast [10 x i8]* [[STACK]] to i8*
|
; CHECK-NEXT: store i8 49, ptr [[STACK]], align 1
|
||||||
; CHECK-NEXT: store i8 49, i8* [[STACK_PTR]], align 1
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, ptr [[STACK]], i64 1
|
||||||
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 1
|
; CHECK-NEXT: store i8 50, ptr [[GEP_1]], align 1
|
||||||
; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1
|
; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr i8, ptr [[STACK]], i64 2
|
||||||
; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 2
|
; CHECK-NEXT: store i8 51, ptr [[GEP_2]], align 1
|
||||||
; CHECK-NEXT: store i8 51, i8* [[GEP_2]], align 1
|
; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr i8, ptr [[STACK]], i64 3
|
||||||
; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 3
|
; CHECK-NEXT: store i8 52, ptr [[GEP_3]], align 1
|
||||||
; CHECK-NEXT: store i8 52, i8* [[GEP_3]], align 1
|
; CHECK-NEXT: [[RES:%.*]] = call ptr @memccpy(ptr [[FOO:%.*]], ptr [[STACK]], i32 42, i64 [[N:%.*]])
|
||||||
; CHECK-NEXT: [[RES:%.*]] = call i8* @memccpy(i8* [[FOO:%.*]], i8* [[STACK_PTR]], i32 42, i64 [[N:%.*]])
|
; CHECK-NEXT: ret ptr [[RES]]
|
||||||
; CHECK-NEXT: ret i8* [[RES]]
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%stack = alloca [10 x i8]
|
%stack = alloca [10 x i8]
|
||||||
%stack.ptr = bitcast [10 x i8]* %stack to i8*
|
store i8 49, ptr %stack, align 1
|
||||||
store i8 49, i8* %stack.ptr, align 1
|
%gep.1 = getelementptr i8, ptr %stack, i64 1
|
||||||
%gep.1 = getelementptr i8, i8* %stack.ptr, i64 1
|
store i8 50, ptr %gep.1, align 1
|
||||||
store i8 50, i8* %gep.1, align 1
|
%gep.2 = getelementptr i8, ptr %stack, i64 2
|
||||||
%gep.2 = getelementptr i8, i8* %stack.ptr, i64 2
|
store i8 51, ptr %gep.2, align 1
|
||||||
store i8 51, i8* %gep.2, align 1
|
%gep.3 = getelementptr i8, ptr %stack, i64 3
|
||||||
%gep.3 = getelementptr i8, i8* %stack.ptr, i64 3
|
store i8 52, ptr %gep.3, align 1
|
||||||
store i8 52, i8* %gep.3, align 1
|
%res = call ptr @memccpy(ptr %foo, ptr %stack, i32 42, i64 %n)
|
||||||
%res = call i8* @memccpy(i8* %foo, i8* %stack.ptr, i32 42, i64 %n)
|
ret ptr %res
|
||||||
ret i8* %res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
; Make sure memccpy does not kill any stores, because it is not known how many
|
; Make sure memccpy does not kill any stores, because it is not known how many
|
||||||
; bytes are written.
|
; bytes are written.
|
||||||
define i8* @test_memccpy_const_size_does_not_kill_stores(i8* noalias %dest, i8* noalias %foo) {
|
define ptr @test_memccpy_const_size_does_not_kill_stores(ptr noalias %dest, ptr noalias %foo) {
|
||||||
; CHECK-LABEL: @test_memccpy_const_size_does_not_kill_stores(
|
; CHECK-LABEL: @test_memccpy_const_size_does_not_kill_stores(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i8 49, i8* [[DEST:%.*]], align 1
|
; CHECK-NEXT: store i8 49, ptr [[DEST:%.*]], align 1
|
||||||
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[DEST]], i64 1
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, ptr [[DEST]], i64 1
|
||||||
; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1
|
; CHECK-NEXT: store i8 50, ptr [[GEP_1]], align 1
|
||||||
; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr i8, i8* [[DEST]], i64 2
|
; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr i8, ptr [[DEST]], i64 2
|
||||||
; CHECK-NEXT: store i8 51, i8* [[GEP_2]], align 1
|
; CHECK-NEXT: store i8 51, ptr [[GEP_2]], align 1
|
||||||
; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr i8, i8* [[DEST]], i64 3
|
; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr i8, ptr [[DEST]], i64 3
|
||||||
; CHECK-NEXT: store i8 52, i8* [[GEP_3]], align 1
|
; CHECK-NEXT: store i8 52, ptr [[GEP_3]], align 1
|
||||||
; CHECK-NEXT: [[RES:%.*]] = call i8* @memccpy(i8* [[DEST]], i8* [[FOO:%.*]], i32 42, i64 2)
|
; CHECK-NEXT: [[RES:%.*]] = call ptr @memccpy(ptr [[DEST]], ptr [[FOO:%.*]], i32 42, i64 2)
|
||||||
; CHECK-NEXT: ret i8* [[RES]]
|
; CHECK-NEXT: ret ptr [[RES]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i8 49, i8* %dest, align 1
|
store i8 49, ptr %dest, align 1
|
||||||
%gep.1 = getelementptr i8, i8* %dest, i64 1
|
%gep.1 = getelementptr i8, ptr %dest, i64 1
|
||||||
store i8 50, i8* %gep.1, align 1
|
store i8 50, ptr %gep.1, align 1
|
||||||
%gep.2 = getelementptr i8, i8* %dest, i64 2
|
%gep.2 = getelementptr i8, ptr %dest, i64 2
|
||||||
store i8 51, i8* %gep.2, align 1
|
store i8 51, ptr %gep.2, align 1
|
||||||
%gep.3 = getelementptr i8, i8* %dest, i64 3
|
%gep.3 = getelementptr i8, ptr %dest, i64 3
|
||||||
store i8 52, i8* %gep.3, align 1
|
store i8 52, ptr %gep.3, align 1
|
||||||
%res = call i8* @memccpy(i8* %dest, i8* %foo, i32 42, i64 2)
|
%res = call ptr @memccpy(ptr %dest, ptr %foo, i32 42, i64 2)
|
||||||
ret i8* %res
|
ret ptr %res
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @dse_strcpy(i8* nocapture readonly %src) {
|
define void @dse_strcpy(ptr nocapture readonly %src) {
|
||||||
; CHECK-LABEL: @dse_strcpy(
|
; CHECK-LABEL: @dse_strcpy(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca [256 x i8], align 16
|
; CHECK-NEXT: [[A:%.*]] = alloca [256 x i8], align 16
|
||||||
; CHECK-NEXT: [[BUF:%.*]] = getelementptr inbounds [256 x i8], [256 x i8]* [[A]], i64 0, i64 0
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 256, ptr nonnull [[A]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull [[BUF]])
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 256, ptr nonnull [[A]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull [[BUF]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca [256 x i8], align 16
|
%a = alloca [256 x i8], align 16
|
||||||
%buf = getelementptr inbounds [256 x i8], [256 x i8]* %a, i64 0, i64 0
|
call void @llvm.lifetime.start.p0(i64 256, ptr nonnull %a)
|
||||||
call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull %buf)
|
call ptr @strcpy(ptr nonnull %a, ptr nonnull dereferenceable(1) %src)
|
||||||
call i8* @strcpy(i8* nonnull %buf, i8* nonnull dereferenceable(1) %src)
|
call void @llvm.lifetime.end.p0(i64 256, ptr nonnull %a)
|
||||||
call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull %buf)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @dse_strncpy(i8* nocapture readonly %src) {
|
define void @dse_strncpy(ptr nocapture readonly %src) {
|
||||||
; CHECK-LABEL: @dse_strncpy(
|
; CHECK-LABEL: @dse_strncpy(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca [256 x i8], align 16
|
; CHECK-NEXT: [[A:%.*]] = alloca [256 x i8], align 16
|
||||||
; CHECK-NEXT: [[BUF:%.*]] = getelementptr inbounds [256 x i8], [256 x i8]* [[A]], i64 0, i64 0
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 256, ptr nonnull [[A]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull [[BUF]])
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 256, ptr nonnull [[A]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull [[BUF]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca [256 x i8], align 16
|
%a = alloca [256 x i8], align 16
|
||||||
%buf = getelementptr inbounds [256 x i8], [256 x i8]* %a, i64 0, i64 0
|
call void @llvm.lifetime.start.p0(i64 256, ptr nonnull %a)
|
||||||
call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull %buf)
|
call ptr @strncpy(ptr nonnull %a, ptr nonnull dereferenceable(1) %src, i64 6)
|
||||||
call i8* @strncpy(i8* nonnull %buf, i8* nonnull dereferenceable(1) %src, i64 6)
|
call void @llvm.lifetime.end.p0(i64 256, ptr nonnull %a)
|
||||||
call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull %buf)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @dse_strcat(i8* nocapture readonly %src) {
|
define void @dse_strcat(ptr nocapture readonly %src) {
|
||||||
; CHECK-LABEL: @dse_strcat(
|
; CHECK-LABEL: @dse_strcat(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca [256 x i8], align 16
|
; CHECK-NEXT: [[A:%.*]] = alloca [256 x i8], align 16
|
||||||
; CHECK-NEXT: [[BUF:%.*]] = getelementptr inbounds [256 x i8], [256 x i8]* [[A]], i64 0, i64 0
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 256, ptr nonnull [[A]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull [[BUF]])
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 256, ptr nonnull [[A]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull [[BUF]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca [256 x i8], align 16
|
%a = alloca [256 x i8], align 16
|
||||||
%buf = getelementptr inbounds [256 x i8], [256 x i8]* %a, i64 0, i64 0
|
call void @llvm.lifetime.start.p0(i64 256, ptr nonnull %a)
|
||||||
call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull %buf)
|
call ptr @strcat(ptr nonnull %a, ptr nonnull dereferenceable(1) %src)
|
||||||
call i8* @strcat(i8* nonnull %buf, i8* nonnull dereferenceable(1) %src)
|
call void @llvm.lifetime.end.p0(i64 256, ptr nonnull %a)
|
||||||
call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull %buf)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @dse_strncat(i8* nocapture readonly %src) {
|
define void @dse_strncat(ptr nocapture readonly %src) {
|
||||||
; CHECK-LABEL: @dse_strncat(
|
; CHECK-LABEL: @dse_strncat(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca [256 x i8], align 16
|
; CHECK-NEXT: [[A:%.*]] = alloca [256 x i8], align 16
|
||||||
; CHECK-NEXT: [[BUF:%.*]] = getelementptr inbounds [256 x i8], [256 x i8]* [[A]], i64 0, i64 0
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 256, ptr nonnull [[A]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull [[BUF]])
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 256, ptr nonnull [[A]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull [[BUF]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca [256 x i8], align 16
|
%a = alloca [256 x i8], align 16
|
||||||
%buf = getelementptr inbounds [256 x i8], [256 x i8]* %a, i64 0, i64 0
|
call void @llvm.lifetime.start.p0(i64 256, ptr nonnull %a)
|
||||||
call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull %buf)
|
call ptr @strncat(ptr nonnull %a, ptr nonnull dereferenceable(1) %src, i64 6)
|
||||||
call i8* @strncat(i8* nonnull %buf, i8* nonnull dereferenceable(1) %src, i64 6)
|
call void @llvm.lifetime.end.p0(i64 256, ptr nonnull %a)
|
||||||
call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull %buf)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)
|
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
|
||||||
declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
|
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
|
||||||
|
|
||||||
declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i1) nounwind
|
declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1) nounwind
|
||||||
|
|
||||||
; Test that strncpy/memset overwriting each other is optimized out
|
; Test that strncpy/memset overwriting each other is optimized out
|
||||||
|
|
||||||
; strncpy -> memset, full overwrite
|
; strncpy -> memset, full overwrite
|
||||||
define void @dse_strncpy_test1(i8* noalias %out, i8* noalias %in) {
|
define void @dse_strncpy_test1(ptr noalias %out, ptr noalias %in) {
|
||||||
; CHECK-LABEL: @dse_strncpy_test1(
|
; CHECK-LABEL: @dse_strncpy_test1(
|
||||||
; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* [[OUT:%.*]], i8 42, i64 100, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr [[OUT:%.*]], i8 42, i64 100, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%call = tail call i8* @strncpy(i8* %out, i8* %in, i64 100)
|
%call = tail call ptr @strncpy(ptr %out, ptr %in, i64 100)
|
||||||
tail call void @llvm.memset.p0i8.i64(i8* %out, i8 42, i64 100, i1 false)
|
tail call void @llvm.memset.p0.i64(ptr %out, i8 42, i64 100, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i8* @__memset_chk(i8* writeonly, i32, i64, i64) argmemonly
|
declare ptr @__memset_chk(ptr writeonly, i32, i64, i64) argmemonly
|
||||||
|
|
||||||
; strncpy -> __memset_chk, full overwrite
|
; strncpy -> __memset_chk, full overwrite
|
||||||
define void @dse_strncpy_memset_chk_test1(i8* noalias %out, i8* noalias %in, i64 %n) {
|
define void @dse_strncpy_memset_chk_test1(ptr noalias %out, ptr noalias %in, i64 %n) {
|
||||||
; CHECK-LABEL: @dse_strncpy_memset_chk_test1(
|
; CHECK-LABEL: @dse_strncpy_memset_chk_test1(
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strncpy(i8* [[OUT:%.*]], i8* [[IN:%.*]], i64 100)
|
; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @strncpy(ptr [[OUT:%.*]], ptr [[IN:%.*]], i64 100)
|
||||||
; CHECK-NEXT: [[CALL_2:%.*]] = tail call i8* @__memset_chk(i8* [[OUT]], i32 42, i64 100, i64 [[N:%.*]])
|
; CHECK-NEXT: [[CALL_2:%.*]] = tail call ptr @__memset_chk(ptr [[OUT]], i32 42, i64 100, i64 [[N:%.*]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%call = tail call i8* @strncpy(i8* %out, i8* %in, i64 100)
|
%call = tail call ptr @strncpy(ptr %out, ptr %in, i64 100)
|
||||||
%call.2 = tail call i8* @__memset_chk(i8* %out, i32 42, i64 100, i64 %n)
|
%call.2 = tail call ptr @__memset_chk(ptr %out, i32 42, i64 100, i64 %n)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @use(i8*)
|
declare void @use(ptr)
|
||||||
|
|
||||||
define void @dse_memset_chk_cannot_eliminates_store(i8* %out, i64 %n) {
|
define void @dse_memset_chk_cannot_eliminates_store(ptr %out, i64 %n) {
|
||||||
; CHECK-LABEL: @dse_memset_chk_cannot_eliminates_store(
|
; CHECK-LABEL: @dse_memset_chk_cannot_eliminates_store(
|
||||||
; CHECK-NEXT: store i8 10, i8* [[OUT:%.*]], align 1
|
; CHECK-NEXT: store i8 10, ptr [[OUT:%.*]], align 1
|
||||||
; CHECK-NEXT: [[CALL_2:%.*]] = tail call i8* @__memset_chk(i8* [[OUT]], i32 42, i64 100, i64 [[N:%.*]])
|
; CHECK-NEXT: [[CALL_2:%.*]] = tail call ptr @__memset_chk(ptr [[OUT]], i32 42, i64 100, i64 [[N:%.*]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i8 10, i8* %out
|
store i8 10, ptr %out
|
||||||
%call.2 = tail call i8* @__memset_chk(i8* %out, i32 42, i64 100, i64 %n)
|
%call.2 = tail call ptr @__memset_chk(ptr %out, i32 42, i64 100, i64 %n)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @dse_memset_chk_eliminates_store_local_object_escapes_after(i64 %n) {
|
define void @dse_memset_chk_eliminates_store_local_object_escapes_after(i64 %n) {
|
||||||
; CHECK-LABEL: @dse_memset_chk_eliminates_store_local_object_escapes_after(
|
; CHECK-LABEL: @dse_memset_chk_eliminates_store_local_object_escapes_after(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca [200 x i8], align 1
|
; CHECK-NEXT: [[A:%.*]] = alloca [200 x i8], align 1
|
||||||
; CHECK-NEXT: [[OUT:%.*]] = bitcast [200 x i8]* [[A]] to i8*
|
; CHECK-NEXT: store i8 10, ptr [[A]], align 1
|
||||||
; CHECK-NEXT: store i8 10, i8* [[OUT]], align 1
|
; CHECK-NEXT: [[OUT_100:%.*]] = getelementptr i8, ptr [[A]], i64 100
|
||||||
; CHECK-NEXT: [[OUT_100:%.*]] = getelementptr i8, i8* [[OUT]], i64 100
|
; CHECK-NEXT: store i8 10, ptr [[OUT_100]], align 1
|
||||||
; CHECK-NEXT: store i8 10, i8* [[OUT_100]], align 1
|
; CHECK-NEXT: [[CALL_2:%.*]] = tail call ptr @__memset_chk(ptr [[A]], i32 42, i64 100, i64 [[N:%.*]])
|
||||||
; CHECK-NEXT: [[CALL_2:%.*]] = tail call i8* @__memset_chk(i8* [[OUT]], i32 42, i64 100, i64 [[N:%.*]])
|
; CHECK-NEXT: call void @use(ptr [[A]])
|
||||||
; CHECK-NEXT: call void @use(i8* [[OUT]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca [200 x i8]
|
%a = alloca [200 x i8]
|
||||||
%out = bitcast [200 x i8]* %a to i8*
|
store i8 10, ptr %a
|
||||||
store i8 10, i8* %out
|
%out.100 = getelementptr i8, ptr %a, i64 100
|
||||||
%out.100 = getelementptr i8, i8* %out, i64 100
|
store i8 10, ptr %out.100
|
||||||
store i8 10, i8* %out.100
|
%call.2 = tail call ptr @__memset_chk(ptr %a, i32 42, i64 100, i64 %n)
|
||||||
%call.2 = tail call i8* @__memset_chk(i8* %out, i32 42, i64 100, i64 %n)
|
call void @use(ptr %a)
|
||||||
call void @use(i8* %out)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @dse_memset_chk_eliminates_store_local_object_escapes_before(i64 %n) {
|
define void @dse_memset_chk_eliminates_store_local_object_escapes_before(i64 %n) {
|
||||||
; CHECK-LABEL: @dse_memset_chk_eliminates_store_local_object_escapes_before(
|
; CHECK-LABEL: @dse_memset_chk_eliminates_store_local_object_escapes_before(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca [200 x i8], align 1
|
; CHECK-NEXT: [[A:%.*]] = alloca [200 x i8], align 1
|
||||||
; CHECK-NEXT: [[OUT:%.*]] = bitcast [200 x i8]* [[A]] to i8*
|
; CHECK-NEXT: call void @use(ptr [[A]])
|
||||||
; CHECK-NEXT: call void @use(i8* [[OUT]])
|
; CHECK-NEXT: store i8 10, ptr [[A]], align 1
|
||||||
; CHECK-NEXT: store i8 10, i8* [[OUT]], align 1
|
; CHECK-NEXT: [[OUT_100:%.*]] = getelementptr i8, ptr [[A]], i64 100
|
||||||
; CHECK-NEXT: [[OUT_100:%.*]] = getelementptr i8, i8* [[OUT]], i64 100
|
; CHECK-NEXT: store i8 0, ptr [[OUT_100]], align 1
|
||||||
; CHECK-NEXT: store i8 0, i8* [[OUT_100]], align 1
|
; CHECK-NEXT: [[CALL_2:%.*]] = tail call ptr @__memset_chk(ptr [[A]], i32 42, i64 100, i64 [[N:%.*]])
|
||||||
; CHECK-NEXT: [[CALL_2:%.*]] = tail call i8* @__memset_chk(i8* [[OUT]], i32 42, i64 100, i64 [[N:%.*]])
|
; CHECK-NEXT: call void @use(ptr [[A]])
|
||||||
; CHECK-NEXT: call void @use(i8* [[OUT]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca [200 x i8]
|
%a = alloca [200 x i8]
|
||||||
%out = bitcast [200 x i8]* %a to i8*
|
call void @use(ptr %a)
|
||||||
call void @use(i8* %out)
|
store i8 10, ptr %a
|
||||||
store i8 10, i8* %out
|
%out.100 = getelementptr i8, ptr %a, i64 100
|
||||||
%out.100 = getelementptr i8, i8* %out, i64 100
|
store i8 0, ptr %out.100
|
||||||
store i8 0, i8* %out.100
|
%call.2 = tail call ptr @__memset_chk(ptr %a, i32 42, i64 100, i64 %n)
|
||||||
%call.2 = tail call i8* @__memset_chk(i8* %out, i32 42, i64 100, i64 %n)
|
call void @use(ptr %a)
|
||||||
call void @use(i8* %out)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; strncpy -> memset, partial overwrite
|
; strncpy -> memset, partial overwrite
|
||||||
define void @dse_strncpy_test2(i8* noalias %out, i8* noalias %in) {
|
define void @dse_strncpy_test2(ptr noalias %out, ptr noalias %in) {
|
||||||
; CHECK-LABEL: @dse_strncpy_test2(
|
; CHECK-LABEL: @dse_strncpy_test2(
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strncpy(i8* [[OUT:%.*]], i8* [[IN:%.*]], i64 100)
|
; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @strncpy(ptr [[OUT:%.*]], ptr [[IN:%.*]], i64 100)
|
||||||
; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* [[OUT]], i8 42, i64 99, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr [[OUT]], i8 42, i64 99, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%call = tail call i8* @strncpy(i8* %out, i8* %in, i64 100)
|
%call = tail call ptr @strncpy(ptr %out, ptr %in, i64 100)
|
||||||
tail call void @llvm.memset.p0i8.i64(i8* %out, i8 42, i64 99, i1 false)
|
tail call void @llvm.memset.p0.i64(ptr %out, i8 42, i64 99, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; strncpy -> memset_chk, partial overwrite
|
; strncpy -> memset_chk, partial overwrite
|
||||||
define void @dse_strncpy_memset_chk_test2(i8* noalias %out, i8* noalias %in, i64 %n) {
|
define void @dse_strncpy_memset_chk_test2(ptr noalias %out, ptr noalias %in, i64 %n) {
|
||||||
; CHECK-LABEL: @dse_strncpy_memset_chk_test2(
|
; CHECK-LABEL: @dse_strncpy_memset_chk_test2(
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strncpy(i8* [[OUT:%.*]], i8* [[IN:%.*]], i64 100)
|
; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @strncpy(ptr [[OUT:%.*]], ptr [[IN:%.*]], i64 100)
|
||||||
; CHECK-NEXT: [[CALL_2:%.*]] = tail call i8* @__memset_chk(i8* [[OUT]], i32 42, i64 99, i64 [[N:%.*]])
|
; CHECK-NEXT: [[CALL_2:%.*]] = tail call ptr @__memset_chk(ptr [[OUT]], i32 42, i64 99, i64 [[N:%.*]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%call = tail call i8* @strncpy(i8* %out, i8* %in, i64 100)
|
%call = tail call ptr @strncpy(ptr %out, ptr %in, i64 100)
|
||||||
%call.2 = tail call i8* @__memset_chk(i8* %out, i32 42, i64 99, i64 %n)
|
%call.2 = tail call ptr @__memset_chk(ptr %out, i32 42, i64 99, i64 %n)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; strncpy -> memset, different destination
|
; strncpy -> memset, different destination
|
||||||
define void @dse_strncpy_test3(i8* noalias %out1, i8* noalias %out2, i8* noalias %in) {
|
define void @dse_strncpy_test3(ptr noalias %out1, ptr noalias %out2, ptr noalias %in) {
|
||||||
; CHECK-LABEL: @dse_strncpy_test3(
|
; CHECK-LABEL: @dse_strncpy_test3(
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strncpy(i8* [[OUT1:%.*]], i8* [[IN:%.*]], i64 100)
|
; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @strncpy(ptr [[OUT1:%.*]], ptr [[IN:%.*]], i64 100)
|
||||||
; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* [[OUT2:%.*]], i8 42, i64 100, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr [[OUT2:%.*]], i8 42, i64 100, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%call = tail call i8* @strncpy(i8* %out1, i8* %in, i64 100)
|
%call = tail call ptr @strncpy(ptr %out1, ptr %in, i64 100)
|
||||||
tail call void @llvm.memset.p0i8.i64(i8* %out2, i8 42, i64 100, i1 false)
|
tail call void @llvm.memset.p0.i64(ptr %out2, i8 42, i64 100, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; strncpy -> memset_chk, different destination
|
; strncpy -> memset_chk, different destination
|
||||||
define void @dse_strncpy_chk_test3(i8* noalias %out1, i8* noalias %out2, i8* noalias %in, i64 %n) {
|
define void @dse_strncpy_chk_test3(ptr noalias %out1, ptr noalias %out2, ptr noalias %in, i64 %n) {
|
||||||
; CHECK-LABEL: @dse_strncpy_chk_test3(
|
; CHECK-LABEL: @dse_strncpy_chk_test3(
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strncpy(i8* [[OUT1:%.*]], i8* [[IN:%.*]], i64 100)
|
; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @strncpy(ptr [[OUT1:%.*]], ptr [[IN:%.*]], i64 100)
|
||||||
; CHECK-NEXT: [[CALL_2:%.*]] = tail call i8* @__memset_chk(i8* [[OUT2:%.*]], i32 42, i64 100, i64 [[N:%.*]])
|
; CHECK-NEXT: [[CALL_2:%.*]] = tail call ptr @__memset_chk(ptr [[OUT2:%.*]], i32 42, i64 100, i64 [[N:%.*]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%call = tail call i8* @strncpy(i8* %out1, i8* %in, i64 100)
|
%call = tail call ptr @strncpy(ptr %out1, ptr %in, i64 100)
|
||||||
%call.2 = tail call i8* @__memset_chk(i8* %out2, i32 42, i64 100, i64 %n)
|
%call.2 = tail call ptr @__memset_chk(ptr %out2, i32 42, i64 100, i64 %n)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; memset -> strncpy, full overwrite
|
; memset -> strncpy, full overwrite
|
||||||
define void @dse_strncpy_test4(i8* noalias %out, i8* noalias %in) {
|
define void @dse_strncpy_test4(ptr noalias %out, ptr noalias %in) {
|
||||||
; CHECK-LABEL: @dse_strncpy_test4(
|
; CHECK-LABEL: @dse_strncpy_test4(
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strncpy(i8* [[OUT:%.*]], i8* [[IN:%.*]], i64 100)
|
; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @strncpy(ptr [[OUT:%.*]], ptr [[IN:%.*]], i64 100)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memset.p0i8.i64(i8* %out, i8 42, i64 100, i1 false)
|
tail call void @llvm.memset.p0.i64(ptr %out, i8 42, i64 100, i1 false)
|
||||||
%call = tail call i8* @strncpy(i8* %out, i8* %in, i64 100)
|
%call = tail call ptr @strncpy(ptr %out, ptr %in, i64 100)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; memset -> strncpy, partial overwrite
|
; memset -> strncpy, partial overwrite
|
||||||
define void @dse_strncpy_test5(i8* noalias %out, i8* noalias %in) {
|
define void @dse_strncpy_test5(ptr noalias %out, ptr noalias %in) {
|
||||||
; CHECK-LABEL: @dse_strncpy_test5(
|
; CHECK-LABEL: @dse_strncpy_test5(
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[OUT:%.*]], i64 99
|
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[OUT:%.*]], i64 99
|
||||||
; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP1]], i8 42, i64 1, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr align 1 [[TMP1]], i8 42, i64 1, i1 false)
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strncpy(i8* [[OUT]], i8* [[IN:%.*]], i64 99)
|
; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @strncpy(ptr [[OUT]], ptr [[IN:%.*]], i64 99)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memset.p0i8.i64(i8* %out, i8 42, i64 100, i1 false)
|
tail call void @llvm.memset.p0.i64(ptr %out, i8 42, i64 100, i1 false)
|
||||||
%call = tail call i8* @strncpy(i8* %out, i8* %in, i64 99)
|
%call = tail call ptr @strncpy(ptr %out, ptr %in, i64 99)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; memset -> strncpy, different destination
|
; memset -> strncpy, different destination
|
||||||
define void @dse_strncpy_test6(i8* noalias %out1, i8* noalias %out2, i8* noalias %in) {
|
define void @dse_strncpy_test6(ptr noalias %out1, ptr noalias %out2, ptr noalias %in) {
|
||||||
; CHECK-LABEL: @dse_strncpy_test6(
|
; CHECK-LABEL: @dse_strncpy_test6(
|
||||||
; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* [[OUT1:%.*]], i8 42, i64 100, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr [[OUT1:%.*]], i8 42, i64 100, i1 false)
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strncpy(i8* [[OUT2:%.*]], i8* [[IN:%.*]], i64 100)
|
; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @strncpy(ptr [[OUT2:%.*]], ptr [[IN:%.*]], i64 100)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memset.p0i8.i64(i8* %out1, i8 42, i64 100, i1 false)
|
tail call void @llvm.memset.p0.i64(ptr %out1, i8 42, i64 100, i1 false)
|
||||||
%call = tail call i8* @strncpy(i8* %out2, i8* %in, i64 100)
|
%call = tail call ptr @strncpy(ptr %out2, ptr %in, i64 100)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,88 +3,83 @@
|
||||||
|
|
||||||
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
|
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
|
||||||
|
|
||||||
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) nounwind
|
declare void @llvm.lifetime.start.p0(i64, ptr nocapture) nounwind
|
||||||
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) nounwind
|
declare void @llvm.lifetime.end.p0(i64, ptr nocapture) nounwind
|
||||||
declare void @llvm.memset.p0i8.i8(i8* nocapture, i8, i8, i1) nounwind
|
declare void @llvm.memset.p0.i8(ptr nocapture, i8, i8, i1) nounwind
|
||||||
|
|
||||||
define void @test1() {
|
define void @test1() {
|
||||||
; CHECK-LABEL: @test1(
|
; CHECK-LABEL: @test1(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1
|
; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* [[A]])
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 1, ptr [[A]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%A = alloca i8
|
%A = alloca i8
|
||||||
|
|
||||||
store i8 0, i8* %A ;; Written to by memset
|
store i8 0, ptr %A ;; Written to by memset
|
||||||
call void @llvm.lifetime.end.p0i8(i64 1, i8* %A)
|
call void @llvm.lifetime.end.p0(i64 1, ptr %A)
|
||||||
|
|
||||||
call void @llvm.memset.p0i8.i8(i8* %A, i8 0, i8 -1, i1 false)
|
call void @llvm.memset.p0.i8(ptr %A, i8 0, i8 -1, i1 false)
|
||||||
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test2(i32* %P) {
|
define void @test2(ptr %P) {
|
||||||
; CHECK-LABEL: @test2(
|
; CHECK-LABEL: @test2(
|
||||||
; CHECK-NEXT: [[Q:%.*]] = getelementptr i32, i32* [[P:%.*]], i32 1
|
; CHECK-NEXT: [[Q:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1
|
||||||
; CHECK-NEXT: [[R:%.*]] = bitcast i32* [[Q]] to i8*
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[Q]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[R]])
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[Q]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[R]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%Q = getelementptr i32, i32* %P, i32 1
|
%Q = getelementptr i32, ptr %P, i32 1
|
||||||
%R = bitcast i32* %Q to i8*
|
call void @llvm.lifetime.start.p0(i64 4, ptr %Q)
|
||||||
call void @llvm.lifetime.start.p0i8(i64 4, i8* %R)
|
store i32 0, ptr %Q ;; This store is dead.
|
||||||
store i32 0, i32* %Q ;; This store is dead.
|
call void @llvm.lifetime.end.p0(i64 4, ptr %Q)
|
||||||
call void @llvm.lifetime.end.p0i8(i64 4, i8* %R)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; lifetime.end only marks the first two bytes of %A as dead. Make sure
|
; lifetime.end only marks the first two bytes of %A as dead. Make sure
|
||||||
; `store i8 20, i8* %A.2 is not removed.
|
; `store i8 20, ptr %A.2 is not removed.
|
||||||
define void @test3_lifetime_end_partial() {
|
define void @test3_lifetime_end_partial() {
|
||||||
; CHECK-LABEL: @test3_lifetime_end_partial(
|
; CHECK-LABEL: @test3_lifetime_end_partial(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[A_0:%.*]] = bitcast i32* [[A]] to i8*
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 2, ptr [[A]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 2, i8* [[A_0]])
|
; CHECK-NEXT: [[A_1:%.*]] = getelementptr i8, ptr [[A]], i64 1
|
||||||
; CHECK-NEXT: [[A_1:%.*]] = getelementptr i8, i8* [[A_0]], i64 1
|
; CHECK-NEXT: [[A_2:%.*]] = getelementptr i8, ptr [[A]], i64 2
|
||||||
; CHECK-NEXT: [[A_2:%.*]] = getelementptr i8, i8* [[A_0]], i64 2
|
; CHECK-NEXT: store i8 20, ptr [[A_2]], align 1
|
||||||
; CHECK-NEXT: store i8 20, i8* [[A_2]], align 1
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 2, ptr [[A]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 2, i8* [[A_0]])
|
; CHECK-NEXT: call void @use(ptr [[A_1]])
|
||||||
; CHECK-NEXT: call void @use(i8* [[A_1]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%A = alloca i32
|
%A = alloca i32
|
||||||
|
|
||||||
%A.0 = bitcast i32 * %A to i8*
|
call void @llvm.lifetime.start.p0(i64 2, ptr %A)
|
||||||
call void @llvm.lifetime.start.p0i8(i64 2, i8* %A.0)
|
%A.1 = getelementptr i8, ptr %A, i64 1
|
||||||
%A.1 = getelementptr i8, i8* %A.0, i64 1
|
%A.2 = getelementptr i8, ptr %A, i64 2
|
||||||
%A.2 = getelementptr i8, i8* %A.0, i64 2
|
|
||||||
|
|
||||||
store i8 0, i8* %A.0
|
store i8 0, ptr %A
|
||||||
store i8 10, i8* %A.1
|
store i8 10, ptr %A.1
|
||||||
store i8 20, i8* %A.2
|
store i8 20, ptr %A.2
|
||||||
|
|
||||||
call void @llvm.lifetime.end.p0i8(i64 2, i8* %A.0)
|
call void @llvm.lifetime.end.p0(i64 2, ptr %A)
|
||||||
call void @use(i8* %A.1)
|
call void @use(ptr %A.1)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; lifetime.end only marks the first two bytes of %A as dead. Make sure
|
; lifetime.end only marks the first two bytes of %A as dead. Make sure
|
||||||
; `store i8 20, i8* %A.2 is not removed.
|
; `store i8 20, ptr %A.2 is not removed.
|
||||||
define void @test4_lifetime_end_partial_loop() {
|
define void @test4_lifetime_end_partial_loop() {
|
||||||
; CHECK-LABEL: @test4_lifetime_end_partial_loop(
|
; CHECK-LABEL: @test4_lifetime_end_partial_loop(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[A_0:%.*]] = bitcast i32* [[A]] to i8*
|
|
||||||
; CHECK-NEXT: br label [[LOOP:%.*]]
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||||||
; CHECK: loop:
|
; CHECK: loop:
|
||||||
; CHECK-NEXT: [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
|
; CHECK-NEXT: [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 2, i8* [[A_0]])
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 2, ptr [[A]])
|
||||||
; CHECK-NEXT: [[A_1:%.*]] = getelementptr i8, i8* [[A_0]], i64 1
|
; CHECK-NEXT: [[A_1:%.*]] = getelementptr i8, ptr [[A]], i64 1
|
||||||
; CHECK-NEXT: [[A_2:%.*]] = getelementptr i8, i8* [[A_0]], i64 2
|
; CHECK-NEXT: [[A_2:%.*]] = getelementptr i8, ptr [[A]], i64 2
|
||||||
; CHECK-NEXT: call void @use(i8* [[A_1]])
|
; CHECK-NEXT: call void @use(ptr [[A_1]])
|
||||||
; CHECK-NEXT: store i8 20, i8* [[A_2]], align 1
|
; CHECK-NEXT: store i8 20, ptr [[A_2]], align 1
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 2, i8* [[A_0]])
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 2, ptr [[A]])
|
||||||
; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 10
|
; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 10
|
||||||
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i8 [[IV_NEXT]], 10
|
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i8 [[IV_NEXT]], 10
|
||||||
; CHECK-NEXT: br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[LOOP]]
|
; CHECK-NEXT: br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[LOOP]]
|
||||||
|
@ -94,21 +89,20 @@ define void @test4_lifetime_end_partial_loop() {
|
||||||
entry:
|
entry:
|
||||||
%A = alloca i32
|
%A = alloca i32
|
||||||
|
|
||||||
%A.0 = bitcast i32 * %A to i8*
|
|
||||||
br label %loop
|
br label %loop
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
|
||||||
call void @llvm.lifetime.start.p0i8(i64 2, i8* %A.0)
|
call void @llvm.lifetime.start.p0(i64 2, ptr %A)
|
||||||
%A.1 = getelementptr i8, i8* %A.0, i64 1
|
%A.1 = getelementptr i8, ptr %A, i64 1
|
||||||
%A.2 = getelementptr i8, i8* %A.0, i64 2
|
%A.2 = getelementptr i8, ptr %A, i64 2
|
||||||
|
|
||||||
call void @use(i8* %A.1)
|
call void @use(ptr %A.1)
|
||||||
|
|
||||||
store i8 20, i8* %A.2
|
store i8 20, ptr %A.2
|
||||||
store i8 10, i8* %A.1
|
store i8 10, ptr %A.1
|
||||||
store i8 0, i8* %A.0
|
store i8 0, ptr %A
|
||||||
call void @llvm.lifetime.end.p0i8(i64 2, i8* %A.0)
|
call void @llvm.lifetime.end.p0(i64 2, ptr %A)
|
||||||
|
|
||||||
%iv.next = add i8 %iv, 10
|
%iv.next = add i8 %iv, 10
|
||||||
%exitcond = icmp eq i8 %iv.next, 10
|
%exitcond = icmp eq i8 %iv.next, 10
|
||||||
|
@ -119,36 +113,34 @@ exit:
|
||||||
}
|
}
|
||||||
|
|
||||||
; lifetime.end only marks the first two bytes of %A as dead. Make sure
|
; lifetime.end only marks the first two bytes of %A as dead. Make sure
|
||||||
; `store i8 20, i8* %A.2 is not removed.
|
; `store i8 20, ptr %A.2 is not removed.
|
||||||
define void @test5_lifetime_end_partial(i32* %A) {
|
define void @test5_lifetime_end_partial(ptr %A) {
|
||||||
; CHECK-LABEL: @test5_lifetime_end_partial(
|
; CHECK-LABEL: @test5_lifetime_end_partial(
|
||||||
; CHECK-NEXT: [[A_0:%.*]] = bitcast i32* [[A:%.*]] to i8*
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 2, ptr [[A:%.*]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 2, i8* [[A_0]])
|
; CHECK-NEXT: [[A_1:%.*]] = getelementptr i8, ptr [[A]], i64 1
|
||||||
; CHECK-NEXT: [[A_1:%.*]] = getelementptr i8, i8* [[A_0]], i64 1
|
; CHECK-NEXT: [[A_2:%.*]] = getelementptr i8, ptr [[A]], i64 2
|
||||||
; CHECK-NEXT: [[A_2:%.*]] = getelementptr i8, i8* [[A_0]], i64 2
|
; CHECK-NEXT: store i8 20, ptr [[A_2]], align 1
|
||||||
; CHECK-NEXT: store i8 20, i8* [[A_2]], align 1
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 2, ptr [[A]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 2, i8* [[A_0]])
|
; CHECK-NEXT: call void @use(ptr [[A_1]])
|
||||||
; CHECK-NEXT: call void @use(i8* [[A_1]])
|
; CHECK-NEXT: store i8 30, ptr [[A_1]], align 1
|
||||||
; CHECK-NEXT: store i8 30, i8* [[A_1]], align 1
|
; CHECK-NEXT: store i8 40, ptr [[A_2]], align 1
|
||||||
; CHECK-NEXT: store i8 40, i8* [[A_2]], align 1
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
|
|
||||||
%A.0 = bitcast i32 * %A to i8*
|
call void @llvm.lifetime.start.p0(i64 2, ptr %A)
|
||||||
call void @llvm.lifetime.start.p0i8(i64 2, i8* %A.0)
|
%A.1 = getelementptr i8, ptr %A, i64 1
|
||||||
%A.1 = getelementptr i8, i8* %A.0, i64 1
|
%A.2 = getelementptr i8, ptr %A, i64 2
|
||||||
%A.2 = getelementptr i8, i8* %A.0, i64 2
|
|
||||||
|
|
||||||
store i8 0, i8* %A.0
|
store i8 0, ptr %A
|
||||||
store i8 10, i8* %A.1
|
store i8 10, ptr %A.1
|
||||||
store i8 20, i8* %A.2
|
store i8 20, ptr %A.2
|
||||||
|
|
||||||
call void @llvm.lifetime.end.p0i8(i64 2, i8* %A.0)
|
call void @llvm.lifetime.end.p0(i64 2, ptr %A)
|
||||||
|
|
||||||
call void @use(i8* %A.1)
|
call void @use(ptr %A.1)
|
||||||
store i8 30, i8* %A.1
|
store i8 30, ptr %A.1
|
||||||
store i8 40, i8* %A.2
|
store i8 40, ptr %A.2
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @use(i8*) readonly
|
declare void @use(ptr) readonly
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
@BUFFER = external dso_local local_unnamed_addr global [0 x i8], align 1
|
@BUFFER = external dso_local local_unnamed_addr global [0 x i8], align 1
|
||||||
|
|
||||||
define void @MissedDSEOpportunity(i64 %idx, i1* noalias %cc) {
|
define void @MissedDSEOpportunity(i64 %idx, ptr noalias %cc) {
|
||||||
;
|
;
|
||||||
; The DSE pass will try to kill the store in the loop exit block using the
|
; The DSE pass will try to kill the store in the loop exit block using the
|
||||||
; store in the function exit block. The loop invariant check on the pointer
|
; store in the function exit block. The loop invariant check on the pointer
|
||||||
|
@ -13,37 +13,35 @@ define void @MissedDSEOpportunity(i64 %idx, i1* noalias %cc) {
|
||||||
;
|
;
|
||||||
; CHECK-LABEL: @MissedDSEOpportunity(
|
; CHECK-LABEL: @MissedDSEOpportunity(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [0 x i8], [0 x i8]* @BUFFER, i64 0, i64 [[IDX:%.*]]
|
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [0 x i8], ptr @BUFFER, i64 0, i64 [[IDX:%.*]]
|
||||||
; CHECK-NEXT: [[BC:%.*]] = bitcast i8* [[GEP]] to i64*
|
; CHECK-NEXT: [[CC0:%.*]] = load volatile i1, ptr [[CC:%.*]], align 1
|
||||||
; CHECK-NEXT: [[CC0:%.*]] = load volatile i1, i1* [[CC:%.*]], align 1
|
|
||||||
; CHECK-NEXT: br i1 [[CC0]], label [[HEAD:%.*]], label [[EXIT:%.*]]
|
; CHECK-NEXT: br i1 [[CC0]], label [[HEAD:%.*]], label [[EXIT:%.*]]
|
||||||
; CHECK: head:
|
; CHECK: head:
|
||||||
; CHECK-NEXT: [[CC1:%.*]] = load volatile i1, i1* [[CC]], align 1
|
; CHECK-NEXT: [[CC1:%.*]] = load volatile i1, ptr [[CC]], align 1
|
||||||
; CHECK-NEXT: br i1 [[CC1]], label [[HEAD]], label [[EXIT_LOOPEXIT:%.*]]
|
; CHECK-NEXT: br i1 [[CC1]], label [[HEAD]], label [[EXIT_LOOPEXIT:%.*]]
|
||||||
; CHECK: exit.loopexit:
|
; CHECK: exit.loopexit:
|
||||||
; CHECK-NEXT: br label [[EXIT]]
|
; CHECK-NEXT: br label [[EXIT]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: store i64 0, i64* [[BC]], align 4
|
; CHECK-NEXT: store i64 0, ptr [[GEP]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
; The entry block cannot have predecessors or be part of a loop
|
; The entry block cannot have predecessors or be part of a loop
|
||||||
%gep = getelementptr inbounds [0 x i8], [0 x i8]* @BUFFER, i64 0, i64 %idx
|
%gep = getelementptr inbounds [0 x i8], ptr @BUFFER, i64 0, i64 %idx
|
||||||
%bc = bitcast i8* %gep to i64*
|
%cc0 = load volatile i1, ptr %cc, align 1
|
||||||
%cc0 = load volatile i1, i1* %cc, align 1
|
|
||||||
br i1 %cc0, label %head, label %exit
|
br i1 %cc0, label %head, label %exit
|
||||||
|
|
||||||
head: ; preds = %entry, %head
|
head: ; preds = %entry, %head
|
||||||
%cc1 = load volatile i1, i1* %cc, align 1
|
%cc1 = load volatile i1, ptr %cc, align 1
|
||||||
br i1 %cc1, label %head, label %exit.loopexit
|
br i1 %cc1, label %head, label %exit.loopexit
|
||||||
|
|
||||||
exit.loopexit: ; preds = %head
|
exit.loopexit: ; preds = %head
|
||||||
; Dead store
|
; Dead store
|
||||||
store i64 2, i64* %bc, align 4
|
store i64 2, ptr %gep, align 4
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit: ; preds = %exit.loopexit, %entry
|
exit: ; preds = %exit.loopexit, %entry
|
||||||
; Killer store
|
; Killer store
|
||||||
store i64 0, i64* %bc, align 4
|
store i64 0, ptr %gep, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
|
@ -2,63 +2,57 @@
|
||||||
; RUN: opt -tbaa -dse -S < %s | FileCheck %s
|
; RUN: opt -tbaa -dse -S < %s | FileCheck %s
|
||||||
target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
|
target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
|
||||||
|
|
||||||
define dllexport i32 @f0(i8** %a0, i8** %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i32 %a7) #0 {
|
define dllexport i32 @f0(ptr %a0, ptr %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i32 %a7) #0 {
|
||||||
; CHECK-LABEL: @f0(
|
; CHECK-LABEL: @f0(
|
||||||
; CHECK-NEXT: b0:
|
; CHECK-NEXT: b0:
|
||||||
; CHECK-NEXT: [[V0:%.*]] = getelementptr inbounds i8*, i8** [[A0:%.*]], i32 [[A2:%.*]]
|
; CHECK-NEXT: [[V0:%.*]] = getelementptr inbounds ptr, ptr [[A0:%.*]], i32 [[A2:%.*]]
|
||||||
; CHECK-NEXT: [[V1:%.*]] = load i8*, i8** [[V0]], align 4, [[TBAA0:!tbaa !.*]]
|
; CHECK-NEXT: [[V1:%.*]] = load ptr, ptr [[V0]], align 4, [[TBAA0:!tbaa !.*]]
|
||||||
; CHECK-NEXT: [[V2:%.*]] = getelementptr i8, i8* [[V1]], i32 [[A3:%.*]]
|
; CHECK-NEXT: [[V2:%.*]] = getelementptr i8, ptr [[V1]], i32 [[A3:%.*]]
|
||||||
; CHECK-NEXT: [[V3:%.*]] = bitcast i8* [[V2]] to <128 x i8>*
|
; CHECK-NEXT: [[V6:%.*]] = getelementptr inbounds ptr, ptr [[A1:%.*]], i32 [[A4:%.*]]
|
||||||
; CHECK-NEXT: [[V6:%.*]] = getelementptr inbounds i8*, i8** [[A1:%.*]], i32 [[A4:%.*]]
|
; CHECK-NEXT: [[V7:%.*]] = load ptr, ptr [[V6]], align 4, [[TBAA3:!tbaa !.*]]
|
||||||
; CHECK-NEXT: [[V7:%.*]] = load i8*, i8** [[V6]], align 4, [[TBAA3:!tbaa !.*]]
|
; CHECK-NEXT: [[V8:%.*]] = getelementptr i8, ptr [[V7]], i32 [[A5:%.*]]
|
||||||
; CHECK-NEXT: [[V8:%.*]] = getelementptr i8, i8* [[V7]], i32 [[A5:%.*]]
|
; CHECK-NEXT: [[V10:%.*]] = tail call <128 x i8> @llvm.masked.load.v128i8.p0(ptr [[V8]], i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <128 x i8> undef), [[TBAA5:!tbaa !.*]]
|
||||||
; CHECK-NEXT: [[V9:%.*]] = bitcast i8* [[V8]] to <128 x i8>*
|
|
||||||
; CHECK-NEXT: [[V10:%.*]] = tail call <128 x i8> @llvm.masked.load.v128i8.p0v128i8(<128 x i8>* [[V9]], i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <128 x i8> undef), [[TBAA5:!tbaa !.*]]
|
|
||||||
; CHECK-NEXT: [[V11:%.*]] = shufflevector <128 x i8> [[V10]], <128 x i8> poison, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
; CHECK-NEXT: [[V11:%.*]] = shufflevector <128 x i8> [[V10]], <128 x i8> poison, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
||||||
; CHECK-NEXT: [[V14:%.*]] = shufflevector <32 x i8> [[V11]], <32 x i8> poison, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
|
; CHECK-NEXT: [[V14:%.*]] = shufflevector <32 x i8> [[V11]], <32 x i8> poison, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
|
||||||
; CHECK-NEXT: [[V16:%.*]] = shufflevector <128 x i8> [[V14]], <128 x i8> poison, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
; CHECK-NEXT: [[V16:%.*]] = shufflevector <128 x i8> [[V14]], <128 x i8> poison, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
||||||
; CHECK-NEXT: [[V17:%.*]] = getelementptr inbounds i8*, i8** [[A1]], i32 [[A6:%.*]]
|
; CHECK-NEXT: [[V17:%.*]] = getelementptr inbounds ptr, ptr [[A1]], i32 [[A6:%.*]]
|
||||||
; CHECK-NEXT: [[V18:%.*]] = load i8*, i8** [[V17]], align 4, [[TBAA3]]
|
; CHECK-NEXT: [[V18:%.*]] = load ptr, ptr [[V17]], align 4, [[TBAA3]]
|
||||||
; CHECK-NEXT: [[V19:%.*]] = getelementptr i8, i8* [[V18]], i32 [[A7:%.*]]
|
; CHECK-NEXT: [[V19:%.*]] = getelementptr i8, ptr [[V18]], i32 [[A7:%.*]]
|
||||||
; CHECK-NEXT: [[V20:%.*]] = bitcast i8* [[V19]] to <128 x i8>*
|
; CHECK-NEXT: [[V21:%.*]] = tail call <128 x i8> @llvm.masked.load.v128i8.p0(ptr [[V19]], i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <128 x i8> undef), [[TBAA5]]
|
||||||
; CHECK-NEXT: [[V21:%.*]] = tail call <128 x i8> @llvm.masked.load.v128i8.p0v128i8(<128 x i8>* [[V20]], i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <128 x i8> undef), [[TBAA5]]
|
|
||||||
; CHECK-NEXT: [[V22:%.*]] = shufflevector <128 x i8> [[V21]], <128 x i8> poison, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
; CHECK-NEXT: [[V22:%.*]] = shufflevector <128 x i8> [[V21]], <128 x i8> poison, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
||||||
; CHECK-NEXT: [[V23:%.*]] = icmp ugt <32 x i8> [[V16]], [[V22]]
|
; CHECK-NEXT: [[V23:%.*]] = icmp ugt <32 x i8> [[V16]], [[V22]]
|
||||||
; CHECK-NEXT: [[V24:%.*]] = select <32 x i1> [[V23]], <32 x i8> [[V16]], <32 x i8> [[V22]]
|
; CHECK-NEXT: [[V24:%.*]] = select <32 x i1> [[V23]], <32 x i8> [[V16]], <32 x i8> [[V22]]
|
||||||
; CHECK-NEXT: [[V25:%.*]] = shufflevector <32 x i8> [[V24]], <32 x i8> poison, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
|
; CHECK-NEXT: [[V25:%.*]] = shufflevector <32 x i8> [[V24]], <32 x i8> poison, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
|
||||||
; CHECK-NEXT: tail call void @llvm.masked.store.v128i8.p0v128i8(<128 x i8> [[V25]], <128 x i8>* [[V3]], i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>), [[TBAA8:!tbaa !.*]]
|
; CHECK-NEXT: tail call void @llvm.masked.store.v128i8.p0(<128 x i8> [[V25]], ptr [[V2]], i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>), [[TBAA8:!tbaa !.*]]
|
||||||
; CHECK-NEXT: ret i32 0
|
; CHECK-NEXT: ret i32 0
|
||||||
;
|
;
|
||||||
b0:
|
b0:
|
||||||
%v0 = getelementptr inbounds i8*, i8** %a0, i32 %a2
|
%v0 = getelementptr inbounds ptr, ptr %a0, i32 %a2
|
||||||
%v1 = load i8*, i8** %v0, align 4, !tbaa !0
|
%v1 = load ptr, ptr %v0, align 4, !tbaa !0
|
||||||
%v2 = getelementptr i8, i8* %v1, i32 %a3
|
%v2 = getelementptr i8, ptr %v1, i32 %a3
|
||||||
%v3 = bitcast i8* %v2 to <128 x i8>*
|
tail call void @llvm.masked.store.v128i8.p0(<128 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef>, ptr %v2, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>), !tbaa !3
|
||||||
tail call void @llvm.masked.store.v128i8.p0v128i8(<128 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef>, <128 x i8>* %v3, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>), !tbaa !3
|
%v6 = getelementptr inbounds ptr, ptr %a1, i32 %a4
|
||||||
%v6 = getelementptr inbounds i8*, i8** %a1, i32 %a4
|
%v7 = load ptr, ptr %v6, align 4, !tbaa !6
|
||||||
%v7 = load i8*, i8** %v6, align 4, !tbaa !6
|
%v8 = getelementptr i8, ptr %v7, i32 %a5
|
||||||
%v8 = getelementptr i8, i8* %v7, i32 %a5
|
%v10 = tail call <128 x i8> @llvm.masked.load.v128i8.p0(ptr %v8, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <128 x i8> undef), !tbaa !8
|
||||||
%v9 = bitcast i8* %v8 to <128 x i8>*
|
|
||||||
%v10 = tail call <128 x i8> @llvm.masked.load.v128i8.p0v128i8(<128 x i8>* %v9, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <128 x i8> undef), !tbaa !8
|
|
||||||
%v11 = shufflevector <128 x i8> %v10, <128 x i8> poison, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
%v11 = shufflevector <128 x i8> %v10, <128 x i8> poison, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
||||||
%v14 = shufflevector <32 x i8> %v11, <32 x i8> poison, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
|
%v14 = shufflevector <32 x i8> %v11, <32 x i8> poison, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
|
||||||
tail call void @llvm.masked.store.v128i8.p0v128i8(<128 x i8> %v14, <128 x i8>* %v3, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>), !tbaa !3
|
tail call void @llvm.masked.store.v128i8.p0(<128 x i8> %v14, ptr %v2, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>), !tbaa !3
|
||||||
%v16 = shufflevector <128 x i8> %v14, <128 x i8> poison, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
%v16 = shufflevector <128 x i8> %v14, <128 x i8> poison, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
||||||
%v17 = getelementptr inbounds i8*, i8** %a1, i32 %a6
|
%v17 = getelementptr inbounds ptr, ptr %a1, i32 %a6
|
||||||
%v18 = load i8*, i8** %v17, align 4, !tbaa !6
|
%v18 = load ptr, ptr %v17, align 4, !tbaa !6
|
||||||
%v19 = getelementptr i8, i8* %v18, i32 %a7
|
%v19 = getelementptr i8, ptr %v18, i32 %a7
|
||||||
%v20 = bitcast i8* %v19 to <128 x i8>*
|
%v21 = tail call <128 x i8> @llvm.masked.load.v128i8.p0(ptr %v19, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <128 x i8> undef), !tbaa !8
|
||||||
%v21 = tail call <128 x i8> @llvm.masked.load.v128i8.p0v128i8(<128 x i8>* %v20, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <128 x i8> undef), !tbaa !8
|
|
||||||
%v22 = shufflevector <128 x i8> %v21, <128 x i8> poison, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
%v22 = shufflevector <128 x i8> %v21, <128 x i8> poison, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
||||||
%v23 = icmp ugt <32 x i8> %v16, %v22
|
%v23 = icmp ugt <32 x i8> %v16, %v22
|
||||||
%v24 = select <32 x i1> %v23, <32 x i8> %v16, <32 x i8> %v22
|
%v24 = select <32 x i1> %v23, <32 x i8> %v16, <32 x i8> %v22
|
||||||
%v25 = shufflevector <32 x i8> %v24, <32 x i8> poison, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
|
%v25 = shufflevector <32 x i8> %v24, <32 x i8> poison, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
|
||||||
tail call void @llvm.masked.store.v128i8.p0v128i8(<128 x i8> %v25, <128 x i8>* %v3, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>), !tbaa !3
|
tail call void @llvm.masked.store.v128i8.p0(<128 x i8> %v25, ptr %v2, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>), !tbaa !3
|
||||||
ret i32 0
|
ret i32 0
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.masked.store.v128i8.p0v128i8(<128 x i8>, <128 x i8>*, i32 immarg, <128 x i1>) #1
|
declare void @llvm.masked.store.v128i8.p0(<128 x i8>, ptr, i32 immarg, <128 x i1>) #1
|
||||||
declare <128 x i8> @llvm.masked.load.v128i8.p0v128i8(<128 x i8>*, i32 immarg, <128 x i1>, <128 x i8>) #2
|
declare <128 x i8> @llvm.masked.load.v128i8.p0(ptr, i32 immarg, <128 x i1>, <128 x i8>) #2
|
||||||
|
|
||||||
attributes #0 = { nounwind willreturn }
|
attributes #0 = { nounwind willreturn }
|
||||||
attributes #1 = { argmemonly nounwind willreturn }
|
attributes #1 = { argmemonly nounwind willreturn }
|
||||||
|
|
|
@ -2,92 +2,82 @@
|
||||||
; RUN: opt -tbaa -dse -S < %s | FileCheck %s
|
; RUN: opt -tbaa -dse -S < %s | FileCheck %s
|
||||||
target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
|
target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
|
||||||
|
|
||||||
define dllexport i32 @f0(i8** %a0, i8** %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i32 %a7) #0 {
|
define dllexport i32 @f0(ptr %a0, ptr %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i32 %a7) #0 {
|
||||||
; CHECK-LABEL: @f0(
|
; CHECK-LABEL: @f0(
|
||||||
; CHECK-NEXT: b0:
|
; CHECK-NEXT: b0:
|
||||||
; CHECK-NEXT: [[V0:%.*]] = getelementptr inbounds i8*, i8** [[A0:%.*]], i32 [[A2:%.*]]
|
; CHECK-NEXT: [[V0:%.*]] = getelementptr inbounds ptr, ptr [[A0:%.*]], i32 [[A2:%.*]]
|
||||||
; CHECK-NEXT: [[V1:%.*]] = load i8*, i8** [[V0]], align 4, !tbaa [[TBAA0:![0-9]+]]
|
; CHECK-NEXT: [[V1:%.*]] = load ptr, ptr [[V0]], align 4, !tbaa [[TBAA0:![0-9]+]]
|
||||||
; CHECK-NEXT: [[V2:%.*]] = getelementptr i8, i8* [[V1]], i32 [[A3:%.*]]
|
; CHECK-NEXT: [[V2:%.*]] = getelementptr i8, ptr [[V1]], i32 [[A3:%.*]]
|
||||||
; CHECK-NEXT: [[V3:%.*]] = bitcast i8* [[V2]] to <128 x i8>*
|
; CHECK-NEXT: [[V6:%.*]] = getelementptr inbounds ptr, ptr [[A1:%.*]], i32 [[A4:%.*]]
|
||||||
; CHECK-NEXT: [[V6:%.*]] = getelementptr inbounds i8*, i8** [[A1:%.*]], i32 [[A4:%.*]]
|
; CHECK-NEXT: [[V7:%.*]] = load ptr, ptr [[V6]], align 4, !tbaa [[TBAA3:![0-9]+]]
|
||||||
; CHECK-NEXT: [[V7:%.*]] = load i8*, i8** [[V6]], align 4, !tbaa [[TBAA3:![0-9]+]]
|
; CHECK-NEXT: [[V8:%.*]] = getelementptr i8, ptr [[V7]], i32 [[A5:%.*]]
|
||||||
; CHECK-NEXT: [[V8:%.*]] = getelementptr i8, i8* [[V7]], i32 [[A5:%.*]]
|
; CHECK-NEXT: [[V10:%.*]] = tail call <128 x i8> @llvm.masked.load.v128i8.p0(ptr [[V8]], i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <128 x i8> undef), !tbaa [[TBAA5:![0-9]+]]
|
||||||
; CHECK-NEXT: [[V9:%.*]] = bitcast i8* [[V8]] to <128 x i8>*
|
|
||||||
; CHECK-NEXT: [[V10:%.*]] = tail call <128 x i8> @llvm.masked.load.v128i8.p0v128i8(<128 x i8>* [[V9]], i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <128 x i8> undef), !tbaa [[TBAA5:![0-9]+]]
|
|
||||||
; CHECK-NEXT: [[V11:%.*]] = shufflevector <128 x i8> [[V10]], <128 x i8> undef, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
; CHECK-NEXT: [[V11:%.*]] = shufflevector <128 x i8> [[V10]], <128 x i8> undef, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
||||||
; CHECK-NEXT: [[V14:%.*]] = shufflevector <32 x i8> [[V11]], <32 x i8> undef, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
|
; CHECK-NEXT: [[V14:%.*]] = shufflevector <32 x i8> [[V11]], <32 x i8> undef, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
|
||||||
; CHECK-NEXT: [[V16:%.*]] = shufflevector <128 x i8> [[V14]], <128 x i8> undef, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
; CHECK-NEXT: [[V16:%.*]] = shufflevector <128 x i8> [[V14]], <128 x i8> undef, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
||||||
; CHECK-NEXT: [[V17:%.*]] = getelementptr inbounds i8*, i8** [[A1]], i32 [[A6:%.*]]
|
; CHECK-NEXT: [[V17:%.*]] = getelementptr inbounds ptr, ptr [[A1]], i32 [[A6:%.*]]
|
||||||
; CHECK-NEXT: [[V18:%.*]] = load i8*, i8** [[V17]], align 4, !tbaa [[TBAA3]]
|
; CHECK-NEXT: [[V18:%.*]] = load ptr, ptr [[V17]], align 4, !tbaa [[TBAA3]]
|
||||||
; CHECK-NEXT: [[V19:%.*]] = getelementptr i8, i8* [[V18]], i32 [[A7:%.*]]
|
; CHECK-NEXT: [[V19:%.*]] = getelementptr i8, ptr [[V18]], i32 [[A7:%.*]]
|
||||||
; CHECK-NEXT: [[V20:%.*]] = bitcast i8* [[V19]] to <128 x i8>*
|
; CHECK-NEXT: [[V21:%.*]] = tail call <128 x i8> @llvm.masked.load.v128i8.p0(ptr [[V19]], i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <128 x i8> undef), !tbaa [[TBAA5]]
|
||||||
; CHECK-NEXT: [[V21:%.*]] = tail call <128 x i8> @llvm.masked.load.v128i8.p0v128i8(<128 x i8>* [[V20]], i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <128 x i8> undef), !tbaa [[TBAA5]]
|
|
||||||
; CHECK-NEXT: [[V22:%.*]] = shufflevector <128 x i8> [[V21]], <128 x i8> undef, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
; CHECK-NEXT: [[V22:%.*]] = shufflevector <128 x i8> [[V21]], <128 x i8> undef, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
||||||
; CHECK-NEXT: [[V23:%.*]] = icmp ugt <32 x i8> [[V16]], [[V22]]
|
; CHECK-NEXT: [[V23:%.*]] = icmp ugt <32 x i8> [[V16]], [[V22]]
|
||||||
; CHECK-NEXT: [[V24:%.*]] = select <32 x i1> [[V23]], <32 x i8> [[V16]], <32 x i8> [[V22]]
|
; CHECK-NEXT: [[V24:%.*]] = select <32 x i1> [[V23]], <32 x i8> [[V16]], <32 x i8> [[V22]]
|
||||||
; CHECK-NEXT: [[V25:%.*]] = shufflevector <32 x i8> [[V24]], <32 x i8> undef, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
|
; CHECK-NEXT: [[V25:%.*]] = shufflevector <32 x i8> [[V24]], <32 x i8> undef, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
|
||||||
; CHECK-NEXT: tail call void @llvm.masked.store.v128i8.p0v128i8(<128 x i8> [[V25]], <128 x i8>* [[V3]], i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>), !tbaa [[TBAA8:![0-9]+]]
|
; CHECK-NEXT: tail call void @llvm.masked.store.v128i8.p0(<128 x i8> [[V25]], ptr [[V2]], i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>), !tbaa [[TBAA8:![0-9]+]]
|
||||||
; CHECK-NEXT: ret i32 0
|
; CHECK-NEXT: ret i32 0
|
||||||
;
|
;
|
||||||
b0:
|
b0:
|
||||||
%v0 = getelementptr inbounds i8*, i8** %a0, i32 %a2
|
%v0 = getelementptr inbounds ptr, ptr %a0, i32 %a2
|
||||||
%v1 = load i8*, i8** %v0, align 4, !tbaa !0
|
%v1 = load ptr, ptr %v0, align 4, !tbaa !0
|
||||||
%v2 = getelementptr i8, i8* %v1, i32 %a3
|
%v2 = getelementptr i8, ptr %v1, i32 %a3
|
||||||
%v3 = bitcast i8* %v2 to <128 x i8>*
|
tail call void @llvm.masked.store.v128i8.p0(<128 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef>, ptr %v2, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>), !tbaa !3
|
||||||
tail call void @llvm.masked.store.v128i8.p0v128i8(<128 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef>, <128 x i8>* %v3, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>), !tbaa !3
|
%v6 = getelementptr inbounds ptr, ptr %a1, i32 %a4
|
||||||
%v6 = getelementptr inbounds i8*, i8** %a1, i32 %a4
|
%v7 = load ptr, ptr %v6, align 4, !tbaa !6
|
||||||
%v7 = load i8*, i8** %v6, align 4, !tbaa !6
|
%v8 = getelementptr i8, ptr %v7, i32 %a5
|
||||||
%v8 = getelementptr i8, i8* %v7, i32 %a5
|
%v10 = tail call <128 x i8> @llvm.masked.load.v128i8.p0(ptr %v8, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <128 x i8> undef), !tbaa !8
|
||||||
%v9 = bitcast i8* %v8 to <128 x i8>*
|
|
||||||
%v10 = tail call <128 x i8> @llvm.masked.load.v128i8.p0v128i8(<128 x i8>* %v9, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <128 x i8> undef), !tbaa !8
|
|
||||||
%v11 = shufflevector <128 x i8> %v10, <128 x i8> undef, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
%v11 = shufflevector <128 x i8> %v10, <128 x i8> undef, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
||||||
%v14 = shufflevector <32 x i8> %v11, <32 x i8> undef, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
|
%v14 = shufflevector <32 x i8> %v11, <32 x i8> undef, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
|
||||||
tail call void @llvm.masked.store.v128i8.p0v128i8(<128 x i8> %v14, <128 x i8>* %v3, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>), !tbaa !3
|
tail call void @llvm.masked.store.v128i8.p0(<128 x i8> %v14, ptr %v2, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>), !tbaa !3
|
||||||
%v16 = shufflevector <128 x i8> %v14, <128 x i8> undef, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
%v16 = shufflevector <128 x i8> %v14, <128 x i8> undef, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
||||||
%v17 = getelementptr inbounds i8*, i8** %a1, i32 %a6
|
%v17 = getelementptr inbounds ptr, ptr %a1, i32 %a6
|
||||||
%v18 = load i8*, i8** %v17, align 4, !tbaa !6
|
%v18 = load ptr, ptr %v17, align 4, !tbaa !6
|
||||||
%v19 = getelementptr i8, i8* %v18, i32 %a7
|
%v19 = getelementptr i8, ptr %v18, i32 %a7
|
||||||
%v20 = bitcast i8* %v19 to <128 x i8>*
|
%v21 = tail call <128 x i8> @llvm.masked.load.v128i8.p0(ptr %v19, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <128 x i8> undef), !tbaa !8
|
||||||
%v21 = tail call <128 x i8> @llvm.masked.load.v128i8.p0v128i8(<128 x i8>* %v20, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <128 x i8> undef), !tbaa !8
|
|
||||||
%v22 = shufflevector <128 x i8> %v21, <128 x i8> undef, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
%v22 = shufflevector <128 x i8> %v21, <128 x i8> undef, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
|
||||||
%v23 = icmp ugt <32 x i8> %v16, %v22
|
%v23 = icmp ugt <32 x i8> %v16, %v22
|
||||||
%v24 = select <32 x i1> %v23, <32 x i8> %v16, <32 x i8> %v22
|
%v24 = select <32 x i1> %v23, <32 x i8> %v16, <32 x i8> %v22
|
||||||
%v25 = shufflevector <32 x i8> %v24, <32 x i8> undef, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
|
%v25 = shufflevector <32 x i8> %v24, <32 x i8> undef, <128 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
|
||||||
tail call void @llvm.masked.store.v128i8.p0v128i8(<128 x i8> %v25, <128 x i8>* %v3, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>), !tbaa !3
|
tail call void @llvm.masked.store.v128i8.p0(<128 x i8> %v25, ptr %v2, i32 32, <128 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>), !tbaa !3
|
||||||
ret i32 0
|
ret i32 0
|
||||||
}
|
}
|
||||||
|
|
||||||
define dllexport i32 @f1(<4 x i32>* %a, <4 x i8> %v1, <4 x i32> %v2) {
|
define dllexport i32 @f1(ptr %a, <4 x i8> %v1, <4 x i32> %v2) {
|
||||||
; CHECK-LABEL: @f1(
|
; CHECK-LABEL: @f1(
|
||||||
; CHECK-NEXT: call void @llvm.masked.store.v4i32.p0v4i32(<4 x i32> [[V2:%.*]], <4 x i32>* [[A:%.*]], i32 1, <4 x i1> <i1 true, i1 true, i1 true, i1 true>)
|
; CHECK-NEXT: call void @llvm.masked.store.v4i32.p0(<4 x i32> [[V2:%.*]], ptr [[A:%.*]], i32 1, <4 x i1> <i1 true, i1 true, i1 true, i1 true>)
|
||||||
; CHECK-NEXT: [[PTR:%.*]] = bitcast <4 x i32>* [[A]] to <4 x i8>*
|
; CHECK-NEXT: call void @llvm.masked.store.v4i8.p0(<4 x i8> [[V1:%.*]], ptr [[A]], i32 1, <4 x i1> <i1 true, i1 true, i1 true, i1 true>)
|
||||||
; CHECK-NEXT: call void @llvm.masked.store.v4i8.p0v4i8(<4 x i8> [[V1:%.*]], <4 x i8>* [[PTR]], i32 1, <4 x i1> <i1 true, i1 true, i1 true, i1 true>)
|
|
||||||
; CHECK-NEXT: ret i32 0
|
; CHECK-NEXT: ret i32 0
|
||||||
;
|
;
|
||||||
tail call void @llvm.masked.store.v4i32.p0(<4 x i32> %v2, <4 x i32>* %a, i32 1, <4 x i1> <i1 true, i1 true, i1 true, i1 true>)
|
tail call void @llvm.masked.store.v4i32.p0(<4 x i32> %v2, ptr %a, i32 1, <4 x i1> <i1 true, i1 true, i1 true, i1 true>)
|
||||||
%ptr = bitcast <4 x i32>* %a to <4 x i8>*
|
tail call void @llvm.masked.store.v4i8.p0(<4 x i8> %v1, ptr %a, i32 1, <4 x i1> <i1 true, i1 true, i1 true, i1 true>)
|
||||||
tail call void @llvm.masked.store.v4i8.p0(<4 x i8> %v1, <4 x i8>* %ptr, i32 1, <4 x i1> <i1 true, i1 true, i1 true, i1 true>)
|
|
||||||
ret i32 0
|
ret i32 0
|
||||||
}
|
}
|
||||||
|
|
||||||
define dllexport i32 @f2(<4 x i32>* %a, <4 x i8> %v1, <4 x i32> %v2, <4 x i1> %mask) {
|
define dllexport i32 @f2(ptr %a, <4 x i8> %v1, <4 x i32> %v2, <4 x i1> %mask) {
|
||||||
; CHECK-LABEL: @f2(
|
; CHECK-LABEL: @f2(
|
||||||
; CHECK-NEXT: call void @llvm.masked.store.v4i32.p0v4i32(<4 x i32> [[V2:%.*]], <4 x i32>* [[A:%.*]], i32 1, <4 x i1> [[MASK:%.*]])
|
; CHECK-NEXT: call void @llvm.masked.store.v4i32.p0(<4 x i32> [[V2:%.*]], ptr [[A:%.*]], i32 1, <4 x i1> [[MASK:%.*]])
|
||||||
; CHECK-NEXT: [[PTR:%.*]] = bitcast <4 x i32>* [[A]] to <4 x i8>*
|
; CHECK-NEXT: call void @llvm.masked.store.v4i8.p0(<4 x i8> [[V1:%.*]], ptr [[A]], i32 1, <4 x i1> [[MASK]])
|
||||||
; CHECK-NEXT: call void @llvm.masked.store.v4i8.p0v4i8(<4 x i8> [[V1:%.*]], <4 x i8>* [[PTR]], i32 1, <4 x i1> [[MASK]])
|
|
||||||
; CHECK-NEXT: ret i32 0
|
; CHECK-NEXT: ret i32 0
|
||||||
;
|
;
|
||||||
tail call void @llvm.masked.store.v4i32.p0(<4 x i32> %v2, <4 x i32>* %a, i32 1, <4 x i1> %mask)
|
tail call void @llvm.masked.store.v4i32.p0(<4 x i32> %v2, ptr %a, i32 1, <4 x i1> %mask)
|
||||||
%ptr = bitcast <4 x i32>* %a to <4 x i8>*
|
tail call void @llvm.masked.store.v4i8.p0(<4 x i8> %v1, ptr %a, i32 1, <4 x i1> %mask)
|
||||||
tail call void @llvm.masked.store.v4i8.p0(<4 x i8> %v1, <4 x i8>* %ptr, i32 1, <4 x i1> %mask)
|
|
||||||
ret i32 0
|
ret i32 0
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.masked.store.v4i8.p0(<4 x i8>, <4 x i8>*, i32, <4 x i1>)
|
declare void @llvm.masked.store.v4i8.p0(<4 x i8>, ptr, i32, <4 x i1>)
|
||||||
declare void @llvm.masked.store.v4i32.p0(<4 x i32>, <4 x i32>*, i32, <4 x i1>)
|
declare void @llvm.masked.store.v4i32.p0(<4 x i32>, ptr, i32, <4 x i1>)
|
||||||
|
|
||||||
declare void @llvm.masked.store.v128i8.p0v128i8(<128 x i8>, <128 x i8>*, i32 immarg, <128 x i1>) #1
|
declare void @llvm.masked.store.v128i8.p0(<128 x i8>, ptr, i32 immarg, <128 x i1>) #1
|
||||||
declare <128 x i8> @llvm.masked.load.v128i8.p0v128i8(<128 x i8>*, i32 immarg, <128 x i1>, <128 x i8>) #2
|
declare <128 x i8> @llvm.masked.load.v128i8.p0(ptr, i32 immarg, <128 x i1>, <128 x i8>) #2
|
||||||
|
|
||||||
attributes #0 = { nounwind willreturn }
|
attributes #0 = { nounwind willreturn }
|
||||||
attributes #1 = { argmemonly nounwind willreturn }
|
attributes #1 = { argmemonly nounwind willreturn }
|
||||||
|
|
|
@ -17,18 +17,17 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||||
define void @foo() #0 !dbg !14 {
|
define void @foo() #0 !dbg !14 {
|
||||||
entry:
|
entry:
|
||||||
%i = alloca i8, align 1
|
%i = alloca i8, align 1
|
||||||
store i8 1, i8* %i, align 1, !dbg !19
|
store i8 1, ptr %i, align 1, !dbg !19
|
||||||
call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !17, metadata !DIExpression()), !dbg !18
|
call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !17, metadata !DIExpression()), !dbg !18
|
||||||
call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !17, metadata !DIExpression()), !dbg !18
|
call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !17, metadata !DIExpression()), !dbg !18
|
||||||
call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !17, metadata !DIExpression()), !dbg !18
|
call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !17, metadata !DIExpression()), !dbg !18
|
||||||
call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !17, metadata !DIExpression()), !dbg !18
|
call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !17, metadata !DIExpression()), !dbg !18
|
||||||
call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !17, metadata !DIExpression()), !dbg !18
|
call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !17, metadata !DIExpression()), !dbg !18
|
||||||
call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !17, metadata !DIExpression()), !dbg !18
|
call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !17, metadata !DIExpression()), !dbg !18
|
||||||
%0 = bitcast [1 x i8]* @g to i8*
|
call void @llvm.memcpy.p0.p0.i64(ptr %i, ptr @g, i64 1, i1 false), !dbg !20
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %i, i8* %0, i64 1, i1 false), !dbg !20
|
|
||||||
br label %bb2
|
br label %bb2
|
||||||
|
|
||||||
bb2: ; preds = %0
|
bb2: ; preds = @g
|
||||||
ret void, !dbg !21
|
ret void, !dbg !21
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +35,7 @@ bb2: ; preds = %0
|
||||||
declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #1
|
declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #1
|
||||||
|
|
||||||
; Function Attrs: argmemonly nounwind
|
; Function Attrs: argmemonly nounwind
|
||||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1) #2
|
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture writeonly, ptr nocapture readonly, i64, i1) #2
|
||||||
|
|
||||||
attributes #0 = { noinline nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
attributes #0 = { noinline nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||||
attributes #1 = { nounwind readnone speculatable }
|
attributes #1 = { nounwind readnone speculatable }
|
||||||
|
|
|
@ -5,156 +5,156 @@
|
||||||
; RUN: opt < %s -aa-pipeline=basic-aa -passes=dse -S | FileCheck %s
|
; RUN: opt < %s -aa-pipeline=basic-aa -passes=dse -S | FileCheck %s
|
||||||
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
|
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
|
||||||
|
|
||||||
declare void @llvm.memset.p0i8.i64(i8* 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
|
declare void @llvm.memset.element.unordered.atomic.p0.i64(ptr nocapture, i8, i64, i32) nounwind
|
||||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
|
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind
|
||||||
declare void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind
|
declare void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i32) nounwind
|
||||||
|
|
||||||
; PR8701
|
; PR8701
|
||||||
|
|
||||||
;; Fully dead overwrite of memcpy.
|
;; Fully dead overwrite of memcpy.
|
||||||
define void @test15(i8* %P, i8* %Q) nounwind ssp {
|
define void @test15(ptr %P, ptr %Q) nounwind ssp {
|
||||||
; CHECK-LABEL: @test15(
|
; CHECK-LABEL: @test15(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P:%.*]], i8* [[Q:%.*]], i64 12, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[P:%.*]], ptr [[Q:%.*]], i64 12, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
;; Fully dead overwrite of memcpy.
|
;; Fully dead overwrite of memcpy.
|
||||||
define void @test15_atomic(i8* %P, i8* %Q) nounwind ssp {
|
define void @test15_atomic(ptr %P, ptr %Q) nounwind ssp {
|
||||||
; CHECK-LABEL: @test15_atomic(
|
; CHECK-LABEL: @test15_atomic(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
|
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i32 1)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
;; Fully dead overwrite of memcpy.
|
;; Fully dead overwrite of memcpy.
|
||||||
define void @test15_atomic_weaker(i8* %P, i8* %Q) nounwind ssp {
|
define void @test15_atomic_weaker(ptr %P, ptr %Q) nounwind ssp {
|
||||||
; CHECK-LABEL: @test15_atomic_weaker(
|
; CHECK-LABEL: @test15_atomic_weaker(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
|
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i32 1)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i1 false)
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
;; Fully dead overwrite of memcpy.
|
;; Fully dead overwrite of memcpy.
|
||||||
define void @test15_atomic_weaker_2(i8* %P, i8* %Q) nounwind ssp {
|
define void @test15_atomic_weaker_2(ptr %P, ptr %Q) nounwind ssp {
|
||||||
; CHECK-LABEL: @test15_atomic_weaker_2(
|
; CHECK-LABEL: @test15_atomic_weaker_2(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
;; Full overwrite of smaller memcpy.
|
;; Full overwrite of smaller memcpy.
|
||||||
define void @test16(i8* %P, i8* %Q) nounwind ssp {
|
define void @test16(ptr %P, ptr %Q) nounwind ssp {
|
||||||
; CHECK-LABEL: @test16(
|
; CHECK-LABEL: @test16(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P:%.*]], i8* [[Q:%.*]], i64 12, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[P:%.*]], ptr [[Q:%.*]], i64 12, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 8, i1 false)
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
;; Full overwrite of smaller memcpy.
|
;; Full overwrite of smaller memcpy.
|
||||||
define void @test16_atomic(i8* %P, i8* %Q) nounwind ssp {
|
define void @test16_atomic(ptr %P, ptr %Q) nounwind ssp {
|
||||||
; CHECK-LABEL: @test16_atomic(
|
; CHECK-LABEL: @test16_atomic(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
|
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i32 1)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 8, i32 1)
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 8, i32 1)
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
;; Full overwrite of smaller memory where overwrite has stronger atomicity
|
;; Full overwrite of smaller memory where overwrite has stronger atomicity
|
||||||
define void @test16_atomic_weaker(i8* %P, i8* %Q) nounwind ssp {
|
define void @test16_atomic_weaker(ptr %P, ptr %Q) nounwind ssp {
|
||||||
; CHECK-LABEL: @test16_atomic_weaker(
|
; CHECK-LABEL: @test16_atomic_weaker(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
|
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i32 1)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 8, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 8, i1 false)
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
;; Full overwrite of smaller memory where overwrite has weaker atomicity.
|
;; Full overwrite of smaller memory where overwrite has weaker atomicity.
|
||||||
define void @test16_atomic_weaker_2(i8* %P, i8* %Q) nounwind ssp {
|
define void @test16_atomic_weaker_2(ptr %P, ptr %Q) nounwind ssp {
|
||||||
; CHECK-LABEL: @test16_atomic_weaker_2(
|
; CHECK-LABEL: @test16_atomic_weaker_2(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 8, i32 1)
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 8, i32 1)
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
;; Overwrite of memset by memcpy.
|
;; Overwrite of memset by memcpy.
|
||||||
define void @test17(i8* %P, i8* noalias %Q) nounwind ssp {
|
define void @test17(ptr %P, ptr noalias %Q) nounwind ssp {
|
||||||
; CHECK-LABEL: @test17(
|
; CHECK-LABEL: @test17(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P:%.*]], i8* [[Q:%.*]], i64 12, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[P:%.*]], ptr [[Q:%.*]], i64 12, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 false)
|
tail call void @llvm.memset.p0.i64(ptr %P, i8 42, i64 8, i1 false)
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
;; Overwrite of memset by memcpy.
|
;; Overwrite of memset by memcpy.
|
||||||
define void @test17_atomic(i8* %P, i8* noalias %Q) nounwind ssp {
|
define void @test17_atomic(ptr %P, ptr noalias %Q) nounwind ssp {
|
||||||
; CHECK-LABEL: @test17_atomic(
|
; CHECK-LABEL: @test17_atomic(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
|
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i32 1)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 1 %P, i8 42, i64 8, i32 1)
|
tail call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 1 %P, i8 42, i64 8, i32 1)
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
;; Overwrite of memset by memcpy. Overwrite is stronger atomicity. We can
|
;; Overwrite of memset by memcpy. Overwrite is stronger atomicity. We can
|
||||||
;; remove the memset.
|
;; remove the memset.
|
||||||
define void @test17_atomic_weaker(i8* %P, i8* noalias %Q) nounwind ssp {
|
define void @test17_atomic_weaker(ptr %P, ptr noalias %Q) nounwind ssp {
|
||||||
; CHECK-LABEL: @test17_atomic_weaker(
|
; CHECK-LABEL: @test17_atomic_weaker(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
|
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i32 1)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memset.p0i8.i64(i8* align 1 %P, i8 42, i64 8, i1 false)
|
tail call void @llvm.memset.p0.i64(ptr align 1 %P, i8 42, i64 8, i1 false)
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
;; Overwrite of memset by memcpy. Overwrite is weaker atomicity. We can remove
|
;; Overwrite of memset by memcpy. Overwrite is weaker atomicity. We can remove
|
||||||
;; the memset.
|
;; the memset.
|
||||||
define void @test17_atomic_weaker_2(i8* %P, i8* noalias %Q) nounwind ssp {
|
define void @test17_atomic_weaker_2(ptr %P, ptr noalias %Q) nounwind ssp {
|
||||||
; CHECK-LABEL: @test17_atomic_weaker_2(
|
; CHECK-LABEL: @test17_atomic_weaker_2(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 1 %P, i8 42, i64 8, i32 1)
|
tail call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 1 %P, i8 42, i64 8, i32 1)
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Should not delete the volatile memset.
|
; Should not delete the volatile memset.
|
||||||
define void @test17v(i8* %P, i8* %Q) nounwind ssp {
|
define void @test17v(ptr %P, ptr %Q) nounwind ssp {
|
||||||
; CHECK-LABEL: @test17v(
|
; CHECK-LABEL: @test17v(
|
||||||
; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* [[P:%.*]], i8 42, i64 8, i1 true)
|
; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr [[P:%.*]], i8 42, i64 8, i1 true)
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P]], i8* [[Q:%.*]], i64 12, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[P]], ptr [[Q:%.*]], i64 12, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 true)
|
tail call void @llvm.memset.p0.i64(ptr %P, i8 42, i64 8, i1 true)
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,25 +165,25 @@ define void @test17v(i8* %P, i8* %Q) nounwind ssp {
|
||||||
;
|
;
|
||||||
; NB! See PR11763 - currently LLVM allows memcpy's source and destination to be
|
; NB! See PR11763 - currently LLVM allows memcpy's source and destination to be
|
||||||
; equal (but not inequal and overlapping).
|
; equal (but not inequal and overlapping).
|
||||||
define void @test18(i8* %P, i8* %Q, i8* %R) nounwind ssp {
|
define void @test18(ptr %P, ptr %Q, ptr %R) nounwind ssp {
|
||||||
; CHECK-LABEL: @test18(
|
; CHECK-LABEL: @test18(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P:%.*]], i8* [[Q:%.*]], i64 12, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[P:%.*]], ptr [[Q:%.*]], i64 12, i1 false)
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P]], i8* [[R:%.*]], i64 12, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[P]], ptr [[R:%.*]], i64 12, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %R, i64 12, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test18_atomic(i8* %P, i8* %Q, i8* %R) nounwind ssp {
|
define void @test18_atomic(ptr %P, ptr %Q, ptr %R) nounwind ssp {
|
||||||
; CHECK-LABEL: @test18_atomic(
|
; CHECK-LABEL: @test18_atomic(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
|
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i32 1)
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[R:%.*]], i64 12, i32 1)
|
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P]], ptr align 1 [[R:%.*]], i64 12, i32 1)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %R, i64 12, i32 1)
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %R, i64 12, i32 1)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,61 +4,55 @@
|
||||||
|
|
||||||
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
|
|
||||||
%struct.Village = type { [4 x %struct.Village*], %struct.Village*, %struct.List, %struct.Hosp, i32, i64 }
|
%struct.Village = type { [4 x ptr], ptr, %struct.List, %struct.Hosp, i32, i64 }
|
||||||
%struct.List = type { %struct.List*, %struct.Patient*, %struct.List* }
|
%struct.List = type { ptr, ptr, ptr }
|
||||||
%struct.Patient = type { i32, i32, i32, %struct.Village* }
|
%struct.Patient = type { i32, i32, i32, ptr }
|
||||||
%struct.Hosp = type { i32, i32, i32, %struct.List, %struct.List, %struct.List, %struct.List }
|
%struct.Hosp = type { i32, i32, i32, %struct.List, %struct.List, %struct.List, %struct.List }
|
||||||
|
|
||||||
declare %struct.Village* @alloc(%struct.Village*)
|
declare ptr @alloc(ptr)
|
||||||
|
|
||||||
define i8* @alloc_tree() {
|
define ptr @alloc_tree() {
|
||||||
; CHECK-LABEL: @alloc_tree(
|
; CHECK-LABEL: @alloc_tree(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[FVAL:%.*]] = alloca [4 x %struct.Village*], align 16
|
; CHECK-NEXT: [[FVAL:%.*]] = alloca [4 x ptr], align 16
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = bitcast [4 x %struct.Village*]* [[FVAL]] to i8*
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[FVAL]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 32, i8* nonnull [[TMP0]])
|
; CHECK-NEXT: [[CALL:%.*]] = tail call dereferenceable_or_null(192) ptr @malloc(i64 192)
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = tail call dereferenceable_or_null(192) i8* @malloc(i64 192)
|
; CHECK-NEXT: [[CALL3:%.*]] = tail call ptr @alloc(ptr [[CALL]])
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[CALL]] to %struct.Village*
|
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [4 x ptr], ptr [[FVAL]], i64 0, i64 3
|
||||||
; CHECK-NEXT: [[CALL3:%.*]] = tail call %struct.Village* @alloc(%struct.Village* [[TMP1]])
|
; CHECK-NEXT: store ptr [[CALL3]], ptr [[ARRAYIDX]], align 8
|
||||||
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [4 x %struct.Village*], [4 x %struct.Village*]* [[FVAL]], i64 0, i64 3
|
; CHECK-NEXT: [[CALL3_1:%.*]] = tail call ptr @alloc(ptr [[CALL]])
|
||||||
; CHECK-NEXT: store %struct.Village* [[CALL3]], %struct.Village** [[ARRAYIDX]], align 8
|
; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds [4 x ptr], ptr [[FVAL]], i64 0, i64 2
|
||||||
; CHECK-NEXT: [[CALL3_1:%.*]] = tail call %struct.Village* @alloc(%struct.Village* [[TMP1]])
|
; CHECK-NEXT: store ptr [[CALL3_1]], ptr [[ARRAYIDX_1]], align 16
|
||||||
; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds [4 x %struct.Village*], [4 x %struct.Village*]* [[FVAL]], i64 0, i64 2
|
; CHECK-NEXT: [[CALL3_2:%.*]] = tail call ptr @alloc(ptr [[CALL]])
|
||||||
; CHECK-NEXT: store %struct.Village* [[CALL3_1]], %struct.Village** [[ARRAYIDX_1]], align 16
|
; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds [4 x ptr], ptr [[FVAL]], i64 0, i64 1
|
||||||
; CHECK-NEXT: [[CALL3_2:%.*]] = tail call %struct.Village* @alloc(%struct.Village* [[TMP1]])
|
; CHECK-NEXT: store ptr [[CALL3_2]], ptr [[ARRAYIDX_2]], align 8
|
||||||
; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds [4 x %struct.Village*], [4 x %struct.Village*]* [[FVAL]], i64 0, i64 1
|
; CHECK-NEXT: [[CALL3_3:%.*]] = tail call ptr @alloc(ptr [[CALL]])
|
||||||
; CHECK-NEXT: store %struct.Village* [[CALL3_2]], %struct.Village** [[ARRAYIDX_2]], align 8
|
; CHECK-NEXT: store ptr [[CALL3_3]], ptr [[FVAL]], align 16
|
||||||
; CHECK-NEXT: [[CALL3_3:%.*]] = tail call %struct.Village* @alloc(%struct.Village* [[TMP1]])
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr nonnull align 8 dereferenceable(32) [[CALL]], ptr nonnull align 16 dereferenceable(32) [[FVAL]], i64 32, i1 false)
|
||||||
; CHECK-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds [4 x %struct.Village*], [4 x %struct.Village*]* [[FVAL]], i64 0, i64 0
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[FVAL]])
|
||||||
; CHECK-NEXT: store %struct.Village* [[CALL3_3]], %struct.Village** [[ARRAYIDX_3]], align 16
|
; CHECK-NEXT: ret ptr [[CALL]]
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 8 dereferenceable(32) [[CALL]], i8* nonnull align 16 dereferenceable(32) [[TMP0]], i64 32, i1 false)
|
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 32, i8* nonnull [[TMP0]])
|
|
||||||
; CHECK-NEXT: ret i8* [[CALL]]
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%fval = alloca [4 x %struct.Village*], align 16
|
%fval = alloca [4 x ptr], align 16
|
||||||
%0 = bitcast [4 x %struct.Village*]* %fval to i8*
|
call void @llvm.lifetime.start.p0(i64 32, ptr nonnull %fval) #7
|
||||||
call void @llvm.lifetime.start.p0i8(i64 32, i8* nonnull %0) #7
|
%call = tail call dereferenceable_or_null(192) ptr @malloc(i64 192) #8
|
||||||
%call = tail call dereferenceable_or_null(192) i8* @malloc(i64 192) #8
|
%call3 = tail call ptr @alloc(ptr %call)
|
||||||
%1 = bitcast i8* %call to %struct.Village*
|
%arrayidx = getelementptr inbounds [4 x ptr], ptr %fval, i64 0, i64 3
|
||||||
%call3 = tail call %struct.Village* @alloc(%struct.Village* %1)
|
store ptr %call3, ptr %arrayidx, align 8
|
||||||
%arrayidx = getelementptr inbounds [4 x %struct.Village*], [4 x %struct.Village*]* %fval, i64 0, i64 3
|
%call3.1 = tail call ptr @alloc(ptr %call)
|
||||||
store %struct.Village* %call3, %struct.Village** %arrayidx, align 8
|
%arrayidx.1 = getelementptr inbounds [4 x ptr], ptr %fval, i64 0, i64 2
|
||||||
%call3.1 = tail call %struct.Village* @alloc(%struct.Village* %1)
|
store ptr %call3.1, ptr %arrayidx.1, align 16
|
||||||
%arrayidx.1 = getelementptr inbounds [4 x %struct.Village*], [4 x %struct.Village*]* %fval, i64 0, i64 2
|
%call3.2 = tail call ptr @alloc(ptr %call)
|
||||||
store %struct.Village* %call3.1, %struct.Village** %arrayidx.1, align 16
|
%arrayidx.2 = getelementptr inbounds [4 x ptr], ptr %fval, i64 0, i64 1
|
||||||
%call3.2 = tail call %struct.Village* @alloc(%struct.Village* %1)
|
store ptr %call3.2, ptr %arrayidx.2, align 8
|
||||||
%arrayidx.2 = getelementptr inbounds [4 x %struct.Village*], [4 x %struct.Village*]* %fval, i64 0, i64 1
|
%call3.3 = tail call ptr @alloc(ptr %call)
|
||||||
store %struct.Village* %call3.2, %struct.Village** %arrayidx.2, align 8
|
store ptr %call3.3, ptr %fval, align 16
|
||||||
%call3.3 = tail call %struct.Village* @alloc(%struct.Village* %1)
|
call void @llvm.memcpy.p0.p0.i64(ptr nonnull align 8 dereferenceable(32) %call, ptr nonnull align 16 dereferenceable(32) %fval, i64 32, i1 false)
|
||||||
%arrayidx.3 = getelementptr inbounds [4 x %struct.Village*], [4 x %struct.Village*]* %fval, i64 0, i64 0
|
call void @llvm.lifetime.end.p0(i64 32, ptr nonnull %fval) #7
|
||||||
store %struct.Village* %call3.3, %struct.Village** %arrayidx.3, align 16
|
ret ptr %call
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 8 dereferenceable(32) %call, i8* nonnull align 16 dereferenceable(32) %0, i64 32, i1 false)
|
|
||||||
call void @llvm.lifetime.end.p0i8(i64 32, i8* nonnull %0) #7
|
|
||||||
ret i8* %call
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)
|
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
|
||||||
declare noalias i8* @malloc(i64)
|
declare noalias ptr @malloc(i64)
|
||||||
declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
|
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
|
||||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg)
|
declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg)
|
||||||
|
|
|
@ -1,63 +1,63 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||||
; RUN: opt -S -dse < %s | FileCheck %s
|
; RUN: opt -S -dse < %s | FileCheck %s
|
||||||
|
|
||||||
declare void @llvm.memcpy.p0i8.p0i8.i8(i8* nocapture, i8* nocapture, i8, i1) nounwind
|
declare void @llvm.memcpy.p0.p0.i8(ptr nocapture, ptr nocapture, i8, i1) nounwind
|
||||||
declare void @llvm.memcpy.inline.p0i8.p0i8.i8(i8* nocapture, i8* nocapture, i8, i1) nounwind
|
declare void @llvm.memcpy.inline.p0.p0.i8(ptr nocapture, ptr nocapture, i8, i1) nounwind
|
||||||
declare void @llvm.memmove.p0i8.p0i8.i8(i8* nocapture, i8* nocapture, i8, i1) nounwind
|
declare void @llvm.memmove.p0.p0.i8(ptr nocapture, ptr nocapture, i8, i1) nounwind
|
||||||
declare void @llvm.memset.p0i8.i8(i8* nocapture, i8, i8, i1) nounwind
|
declare void @llvm.memset.p0.i8(ptr nocapture, i8, i8, i1) nounwind
|
||||||
|
|
||||||
define void @test1(i8* noalias %A, i8* noalias %B) {
|
define void @test1(ptr noalias %A, ptr noalias %B) {
|
||||||
; CHECK-LABEL: @test1(
|
; CHECK-LABEL: @test1(
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i8(i8* [[A:%.*]], i8* [[B:%.*]], i8 12, i1 false)
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i8(ptr [[A:%.*]], ptr [[B:%.*]], i8 12, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i8 0, i8* %A ;; Written to by memcpy
|
store i8 0, ptr %A ;; Written to by memcpy
|
||||||
|
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i8(i8* %A, i8* %B, i8 12, i1 false)
|
call void @llvm.memcpy.p0.p0.i8(ptr %A, ptr %B, i8 12, i1 false)
|
||||||
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test2(i8* noalias %A, i8* noalias %B) {
|
define void @test2(ptr noalias %A, ptr noalias %B) {
|
||||||
; CHECK-LABEL: @test2(
|
; CHECK-LABEL: @test2(
|
||||||
; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i8(i8* [[A]], i8* [[B:%.*]], i8 12, i1 false)
|
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i8(ptr [[A]], ptr [[B:%.*]], i8 12, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i8 0, i8* %A ;; Written to by memmove
|
store i8 0, ptr %A ;; Written to by memmove
|
||||||
|
|
||||||
call void @llvm.memmove.p0i8.p0i8.i8(i8* %A, i8* %B, i8 12, i1 false)
|
call void @llvm.memmove.p0.p0.i8(ptr %A, ptr %B, i8 12, i1 false)
|
||||||
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test2a(i8* %A, i8* %B) {
|
define void @test2a(ptr %A, ptr %B) {
|
||||||
; CHECK-LABEL: @test2a(
|
; CHECK-LABEL: @test2a(
|
||||||
; CHECK-NEXT: store i8 0, i8* [[A:%.*]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[A:%.*]], align 1
|
||||||
; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i8(i8* [[A]], i8* [[B:%.*]], i8 12, i1 false)
|
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i8(ptr [[A]], ptr [[B:%.*]], i8 12, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i8 0, i8* %A ;; Written to by memmove
|
store i8 0, ptr %A ;; Written to by memmove
|
||||||
|
|
||||||
call void @llvm.memmove.p0i8.p0i8.i8(i8* %A, i8* %B, i8 12, i1 false)
|
call void @llvm.memmove.p0.p0.i8(ptr %A, ptr %B, i8 12, i1 false)
|
||||||
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test3(i8* noalias %A) {
|
define void @test3(ptr noalias %A) {
|
||||||
; CHECK-LABEL: @test3(
|
; CHECK-LABEL: @test3(
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i8(i8* [[A:%.*]], i8 0, i8 12, i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i8(ptr [[A:%.*]], i8 0, i8 12, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i8 0, i8* %A ;; Written to by memset
|
store i8 0, ptr %A ;; Written to by memset
|
||||||
|
|
||||||
call void @llvm.memset.p0i8.i8(i8* %A, i8 0, i8 12, i1 false)
|
call void @llvm.memset.p0.i8(ptr %A, i8 0, i8 12, i1 false)
|
||||||
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.memcpy.element.unordered.atomic.p0i16.p0i16.i16(i16* nocapture, i16* nocapture, i16, i32) nounwind
|
declare void @llvm.memcpy.element.unordered.atomic.p0.p0.i16(ptr nocapture, ptr nocapture, i16, i32) nounwind
|
||||||
declare void @llvm.memmove.element.unordered.atomic.p0i16.p0i16.i16(i16* nocapture, i16* nocapture, i16, i32) nounwind
|
declare void @llvm.memmove.element.unordered.atomic.p0.p0.i16(ptr nocapture, ptr nocapture, i16, i32) nounwind
|
||||||
declare void @llvm.memset.element.unordered.atomic.p0i16.i16(i16* nocapture, i8, i16, i32) nounwind
|
declare void @llvm.memset.element.unordered.atomic.p0.i16(ptr nocapture, i8, i16, i32) nounwind
|
||||||
|
|
||||||
|
|
||||||
define void @test4() {
|
define void @test4() {
|
||||||
|
@ -67,10 +67,10 @@ define void @test4() {
|
||||||
%A = alloca i16, i16 1024, align 2
|
%A = alloca i16, i16 1024, align 2
|
||||||
%B = alloca i16, i16 1024, align 2
|
%B = alloca i16, i16 1024, align 2
|
||||||
|
|
||||||
store atomic i16 0, i16* %A unordered, align 2 ;; Written to by memcpy
|
store atomic i16 0, ptr %A unordered, align 2 ;; Written to by memcpy
|
||||||
store atomic i16 0, i16* %B unordered, align 2 ;; Read by memcpy
|
store atomic i16 0, ptr %B unordered, align 2 ;; Read by memcpy
|
||||||
|
|
||||||
call void @llvm.memcpy.element.unordered.atomic.p0i16.p0i16.i16(i16* align 2 %A, i16* align 2 %B, i16 1024, i32 2)
|
call void @llvm.memcpy.element.unordered.atomic.p0.p0.i16(ptr align 2 %A, ptr align 2 %B, i16 1024, i32 2)
|
||||||
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -82,10 +82,10 @@ define void @test5() {
|
||||||
%A = alloca i16, i16 1024, align 2
|
%A = alloca i16, i16 1024, align 2
|
||||||
%B = alloca i16, i16 1024, align 2
|
%B = alloca i16, i16 1024, align 2
|
||||||
|
|
||||||
store atomic i16 0, i16* %A unordered, align 2 ;; Written to by memmove
|
store atomic i16 0, ptr %A unordered, align 2 ;; Written to by memmove
|
||||||
store atomic i16 0, i16* %B unordered, align 2 ;; Read by memmove
|
store atomic i16 0, ptr %B unordered, align 2 ;; Read by memmove
|
||||||
|
|
||||||
call void @llvm.memmove.element.unordered.atomic.p0i16.p0i16.i16(i16* align 2 %A, i16* align 2 %B, i16 1024, i32 2)
|
call void @llvm.memmove.element.unordered.atomic.p0.p0.i16(ptr align 2 %A, ptr align 2 %B, i16 1024, i32 2)
|
||||||
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -98,21 +98,21 @@ define void @test6() {
|
||||||
%A = alloca i16, i16 1024, align 2
|
%A = alloca i16, i16 1024, align 2
|
||||||
%B = alloca i16, i16 1024, align 2
|
%B = alloca i16, i16 1024, align 2
|
||||||
|
|
||||||
store atomic i16 0, i16* %A unordered, align 2 ;; Written to by memset
|
store atomic i16 0, ptr %A unordered, align 2 ;; Written to by memset
|
||||||
|
|
||||||
call void @llvm.memset.element.unordered.atomic.p0i16.i16(i16* align 2 %A, i8 0, i16 1024, i32 2)
|
call void @llvm.memset.element.unordered.atomic.p0.i16(ptr align 2 %A, i8 0, i16 1024, i32 2)
|
||||||
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test7(i8* noalias %A, i8* noalias %B) {
|
define void @test7(ptr noalias %A, ptr noalias %B) {
|
||||||
; CHECK-LABEL: @test7(
|
; CHECK-LABEL: @test7(
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.inline.p0i8.p0i8.i8(i8* [[A:%.*]], i8* [[B:%.*]], i8 12, i1 false)
|
; CHECK-NEXT: call void @llvm.memcpy.inline.p0.p0.i8(ptr [[A:%.*]], ptr [[B:%.*]], i8 12, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i8 0, i8* %A ;; Written to by memcpy
|
store i8 0, ptr %A ;; Written to by memcpy
|
||||||
|
|
||||||
call void @llvm.memcpy.inline.p0i8.p0i8.i8(i8* %A, i8* %B, i8 12, i1 false)
|
call void @llvm.memcpy.inline.p0.p0.i8(ptr %A, ptr %B, i8 12, i1 false)
|
||||||
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,353 +1,349 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||||
; RUN: opt -dse -S %s | FileCheck %s
|
; RUN: opt -dse -S %s | FileCheck %s
|
||||||
|
|
||||||
define void @memset_equal_size_values(i8* %ptr, i64 %len) {
|
define void @memset_equal_size_values(ptr %ptr, i64 %len) {
|
||||||
; CHECK-LABEL: @memset_equal_size_values(
|
; CHECK-LABEL: @memset_equal_size_values(
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[PTR:%.*]], i8 0, i64 [[LEN:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[PTR:%.*]], i8 0, i64 [[LEN:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %ptr, i8 0, i64 %len, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %ptr, i8 0, i64 %len, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %ptr, i8 0, i64 %len, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %ptr, i8 0, i64 %len, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memset_different_size_values_1(i8* %ptr, i64 %len.1, i64 %len.2) {
|
define void @memset_different_size_values_1(ptr %ptr, i64 %len.1, i64 %len.2) {
|
||||||
; CHECK-LABEL: @memset_different_size_values_1(
|
; CHECK-LABEL: @memset_different_size_values_1(
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[PTR:%.*]], i8 0, i64 [[LEN_1:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[PTR:%.*]], i8 0, i64 [[LEN_1:%.*]], i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[PTR]], i8 0, i64 [[LEN_2:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[PTR]], i8 0, i64 [[LEN_2:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %ptr, i8 0, i64 %len.1, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %ptr, i8 0, i64 %len.1, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %ptr, i8 0, i64 %len.2, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %ptr, i8 0, i64 %len.2, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memset_different_size_values_2(i8* %ptr, i64 %len) {
|
define void @memset_different_size_values_2(ptr %ptr, i64 %len) {
|
||||||
; CHECK-LABEL: @memset_different_size_values_2(
|
; CHECK-LABEL: @memset_different_size_values_2(
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[PTR:%.*]], i8 0, i64 [[LEN:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[PTR:%.*]], i8 0, i64 [[LEN:%.*]], i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[PTR]], i8 0, i64 100, i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[PTR]], i8 0, i64 100, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %ptr, i8 0, i64 %len, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %ptr, i8 0, i64 %len, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %ptr, i8 0, i64 100, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %ptr, i8 0, i64 100, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memset_different_size_values_3(i8* %ptr, i64 %len) {
|
define void @memset_different_size_values_3(ptr %ptr, i64 %len) {
|
||||||
; CHECK-LABEL: @memset_different_size_values_3(
|
; CHECK-LABEL: @memset_different_size_values_3(
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[PTR:%.*]], i8 0, i64 100, i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[PTR:%.*]], i8 0, i64 100, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[PTR]], i8 0, i64 [[LEN:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[PTR]], i8 0, i64 [[LEN:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %ptr, i8 0, i64 100, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %ptr, i8 0, i64 100, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %ptr, i8 0, i64 %len, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %ptr, i8 0, i64 %len, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memset_and_store_1(i8* %ptr, i64 %len) {
|
define void @memset_and_store_1(ptr %ptr, i64 %len) {
|
||||||
; CHECK-LABEL: @memset_and_store_1(
|
; CHECK-LABEL: @memset_and_store_1(
|
||||||
; CHECK-NEXT: [[BC:%.*]] = bitcast i8* [[PTR:%.*]] to i64*
|
; CHECK-NEXT: store i64 123, ptr [[PTR:%.*]], align 4
|
||||||
; CHECK-NEXT: store i64 123, i64* [[BC]], align 4
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[PTR]], i8 0, i64 [[LEN:%.*]], i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[PTR]], i8 0, i64 [[LEN:%.*]], i1 false)
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%bc = bitcast i8* %ptr to i64*
|
store i64 123, ptr %ptr
|
||||||
store i64 123, i64* %bc
|
call void @llvm.memset.p0.i64(ptr align 1 %ptr, i8 0, i64 %len, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %ptr, i8 0, i64 %len, i1 false)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memset_and_store_2(i8* %ptr, i64 %len) {
|
define void @memset_and_store_2(ptr %ptr, i64 %len) {
|
||||||
; CHECK-LABEL: @memset_and_store_2(
|
; CHECK-LABEL: @memset_and_store_2(
|
||||||
; CHECK-NEXT: [[BC:%.*]] = bitcast i8* [[PTR:%.*]] to i64*
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[PTR:%.*]], i8 0, i64 [[LEN:%.*]], i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[PTR]], i8 0, i64 [[LEN:%.*]], i1 false)
|
; CHECK-NEXT: store i64 123, ptr [[PTR]], align 4
|
||||||
; CHECK-NEXT: store i64 123, i64* [[BC]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%bc = bitcast i8* %ptr to i64*
|
call void @llvm.memset.p0.i64(ptr align 1 %ptr, i8 0, i64 %len, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %ptr, i8 0, i64 %len, i1 false)
|
store i64 123, ptr %ptr
|
||||||
store i64 123, i64* %bc
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memcpy_equal_size_values(i8* noalias %src, i8* noalias %dst, i64 %len) {
|
define void @memcpy_equal_size_values(ptr noalias %src, ptr noalias %dst, i64 %len) {
|
||||||
; CHECK-LABEL: @memcpy_equal_size_values(
|
; CHECK-LABEL: @memcpy_equal_size_values(
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memcpy_different_size_values_1(i8* noalias %src, i8* noalias %dst, i64 %len.1, i64 %len.2) {
|
define void @memcpy_different_size_values_1(ptr noalias %src, ptr noalias %dst, i64 %len.1, i64 %len.2) {
|
||||||
; CHECK-LABEL: @memcpy_different_size_values_1(
|
; CHECK-LABEL: @memcpy_different_size_values_1(
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[LEN_1:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 [[LEN_1:%.*]], i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC]], i64 [[LEN_2:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr [[SRC]], i64 [[LEN_2:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len.1, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %len.1, i1 false)
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len.2, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %len.2, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memcpy_different_size_values_2(i8* noalias %src, i8* noalias %dst, i64 %len) {
|
define void @memcpy_different_size_values_2(ptr noalias %src, ptr noalias %dst, i64 %len) {
|
||||||
; CHECK-LABEL: @memcpy_different_size_values_2(
|
; CHECK-LABEL: @memcpy_different_size_values_2(
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC]], i64 100, i1 false)
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr [[SRC]], i64 100, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 100, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 100, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memcpy_different_size_values_3(i8* noalias %src, i8* noalias %dst, i64 %len) {
|
define void @memcpy_different_size_values_3(ptr noalias %src, ptr noalias %dst, i64 %len) {
|
||||||
; CHECK-LABEL: @memcpy_different_size_values_3(
|
; CHECK-LABEL: @memcpy_different_size_values_3(
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 100, i1 false)
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 100, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC]], i64 [[LEN:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr [[SRC]], i64 [[LEN:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 100, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 100, i1 false)
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memset_and_memcpy_equal_size_values(i8* noalias %src, i8* noalias %dst, i64 %len) {
|
define void @memset_and_memcpy_equal_size_values(ptr noalias %src, ptr noalias %dst, i64 %len) {
|
||||||
; CHECK-LABEL: @memset_and_memcpy_equal_size_values(
|
; CHECK-LABEL: @memset_and_memcpy_equal_size_values(
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %dst, i8 0, i64 %len, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 0, i64 %len, i1 false)
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memset_and_memcpy_different_size_values_1(i8* noalias %src, i8* noalias %dst, i64 %len.1, i64 %len.2) {
|
define void @memset_and_memcpy_different_size_values_1(ptr noalias %src, ptr noalias %dst, i64 %len.1, i64 %len.2) {
|
||||||
; CHECK-LABEL: @memset_and_memcpy_different_size_values_1(
|
; CHECK-LABEL: @memset_and_memcpy_different_size_values_1(
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[DST:%.*]], i8 0, i64 [[LEN_1:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[DST:%.*]], i8 0, i64 [[LEN_1:%.*]], i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC:%.*]], i64 [[LEN_2:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr [[SRC:%.*]], i64 [[LEN_2:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %dst, i8 0, i64 %len.1, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 0, i64 %len.1, i1 false)
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len.2, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %len.2, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memset_and_memcpy_different_size_values_2(i8* noalias %src, i8* noalias %dst, i64 %len.1) {
|
define void @memset_and_memcpy_different_size_values_2(ptr noalias %src, ptr noalias %dst, i64 %len.1) {
|
||||||
; CHECK-LABEL: @memset_and_memcpy_different_size_values_2(
|
; CHECK-LABEL: @memset_and_memcpy_different_size_values_2(
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[DST:%.*]], i8 0, i64 [[LEN_1:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[DST:%.*]], i8 0, i64 [[LEN_1:%.*]], i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC:%.*]], i64 100, i1 false)
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr [[SRC:%.*]], i64 100, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %dst, i8 0, i64 %len.1, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 0, i64 %len.1, i1 false)
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 100, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 100, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memset_and_memcpy_different_size_values_3(i8* noalias %src, i8* noalias %dst, i64 %len.1) {
|
define void @memset_and_memcpy_different_size_values_3(ptr noalias %src, ptr noalias %dst, i64 %len.1) {
|
||||||
; CHECK-LABEL: @memset_and_memcpy_different_size_values_3(
|
; CHECK-LABEL: @memset_and_memcpy_different_size_values_3(
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[DST:%.*]], i8 0, i64 100, i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[DST:%.*]], i8 0, i64 100, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC:%.*]], i64 [[LEN_1:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr [[SRC:%.*]], i64 [[LEN_1:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %dst, i8 0, i64 100, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 0, i64 100, i1 false)
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len.1, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %len.1, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memcpy_and_memset_equal_size_values(i8* noalias %src, i8* noalias %dst, i64 %len) {
|
define void @memcpy_and_memset_equal_size_values(ptr noalias %src, ptr noalias %dst, i64 %len) {
|
||||||
; CHECK-LABEL: @memcpy_and_memset_equal_size_values(
|
; CHECK-LABEL: @memcpy_and_memset_equal_size_values(
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[DST:%.*]], i8 0, i64 [[LEN:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[DST:%.*]], i8 0, i64 [[LEN:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %dst, i8 0, i64 %len, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 0, i64 %len, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memcpy_and_memset_different_size_values_1(i8* noalias %src, i8* noalias %dst, i64 %len.1, i64 %len.2) {
|
define void @memcpy_and_memset_different_size_values_1(ptr noalias %src, ptr noalias %dst, i64 %len.1, i64 %len.2) {
|
||||||
; CHECK-LABEL: @memcpy_and_memset_different_size_values_1(
|
; CHECK-LABEL: @memcpy_and_memset_different_size_values_1(
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[LEN_1:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 [[LEN_1:%.*]], i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[DST]], i8 0, i64 [[LEN_2:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[DST]], i8 0, i64 [[LEN_2:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len.1, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %len.1, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %dst, i8 0, i64 %len.2, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 0, i64 %len.2, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memcpy_and_memset_different_size_values_2(i8* noalias %src, i8* noalias %dst, i64 %len.1) {
|
define void @memcpy_and_memset_different_size_values_2(ptr noalias %src, ptr noalias %dst, i64 %len.1) {
|
||||||
; CHECK-LABEL: @memcpy_and_memset_different_size_values_2(
|
; CHECK-LABEL: @memcpy_and_memset_different_size_values_2(
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[LEN_1:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 [[LEN_1:%.*]], i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[DST]], i8 0, i64 100, i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[DST]], i8 0, i64 100, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len.1, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %len.1, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %dst, i8 0, i64 100, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 0, i64 100, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memcpy_and_memset_different_size_values_3(i8* noalias %src, i8* noalias %dst, i64 %len.1) {
|
define void @memcpy_and_memset_different_size_values_3(ptr noalias %src, ptr noalias %dst, i64 %len.1) {
|
||||||
; CHECK-LABEL: @memcpy_and_memset_different_size_values_3(
|
; CHECK-LABEL: @memcpy_and_memset_different_size_values_3(
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 100, i1 false)
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 100, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[DST]], i8 0, i64 [[LEN_1:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[DST]], i8 0, i64 [[LEN_1:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 100, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 100, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %dst, i8 0, i64 %len.1, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 0, i64 %len.1, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memmove_equal_size_values(i8* noalias %src, i8* noalias %dst, i64 %len) {
|
define void @memmove_equal_size_values(ptr noalias %src, ptr noalias %dst, i64 %len) {
|
||||||
; CHECK-LABEL: @memmove_equal_size_values(
|
; CHECK-LABEL: @memmove_equal_size_values(
|
||||||
; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len, i1 false)
|
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
|
||||||
call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len, i1 false)
|
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memmove_different_size_values_1(i8* noalias %src, i8* noalias %dst, i64 %len.1, i64 %len.2) {
|
define void @memmove_different_size_values_1(ptr noalias %src, ptr noalias %dst, i64 %len.1, i64 %len.2) {
|
||||||
; CHECK-LABEL: @memmove_different_size_values_1(
|
; CHECK-LABEL: @memmove_different_size_values_1(
|
||||||
; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[LEN_1:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 [[LEN_1:%.*]], i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC]], i64 [[LEN_2:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr [[DST]], ptr [[SRC]], i64 [[LEN_2:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len.1, i1 false)
|
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %len.1, i1 false)
|
||||||
call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len.2, i1 false)
|
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %len.2, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memmove_different_size_values_2(i8* noalias %src, i8* noalias %dst, i64 %len) {
|
define void @memmove_different_size_values_2(ptr noalias %src, ptr noalias %dst, i64 %len) {
|
||||||
; CHECK-LABEL: @memmove_different_size_values_2(
|
; CHECK-LABEL: @memmove_different_size_values_2(
|
||||||
; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC]], i64 100, i1 false)
|
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr [[DST]], ptr [[SRC]], i64 100, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len, i1 false)
|
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
|
||||||
call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 100, i1 false)
|
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 100, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memmove_different_size_values_3(i8* noalias %src, i8* noalias %dst, i64 %len) {
|
define void @memmove_different_size_values_3(ptr noalias %src, ptr noalias %dst, i64 %len) {
|
||||||
; CHECK-LABEL: @memmove_different_size_values_3(
|
; CHECK-LABEL: @memmove_different_size_values_3(
|
||||||
; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 100, i1 false)
|
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 100, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC]], i64 [[LEN:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr [[DST]], ptr [[SRC]], i64 [[LEN:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 100, i1 false)
|
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 100, i1 false)
|
||||||
call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len, i1 false)
|
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memset_and_memmove_equal_size_values(i8* noalias %src, i8* noalias %dst, i64 %len) {
|
define void @memset_and_memmove_equal_size_values(ptr noalias %src, ptr noalias %dst, i64 %len) {
|
||||||
; CHECK-LABEL: @memset_and_memmove_equal_size_values(
|
; CHECK-LABEL: @memset_and_memmove_equal_size_values(
|
||||||
; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %dst, i8 0, i64 %len, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 0, i64 %len, i1 false)
|
||||||
call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len, i1 false)
|
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memset_and_memmove_different_size_values_1(i8* noalias %src, i8* noalias %dst, i64 %len.1, i64 %len.2) {
|
define void @memset_and_memmove_different_size_values_1(ptr noalias %src, ptr noalias %dst, i64 %len.1, i64 %len.2) {
|
||||||
; CHECK-LABEL: @memset_and_memmove_different_size_values_1(
|
; CHECK-LABEL: @memset_and_memmove_different_size_values_1(
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[DST:%.*]], i8 0, i64 [[LEN_1:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[DST:%.*]], i8 0, i64 [[LEN_1:%.*]], i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC:%.*]], i64 [[LEN_2:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr [[DST]], ptr [[SRC:%.*]], i64 [[LEN_2:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %dst, i8 0, i64 %len.1, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 0, i64 %len.1, i1 false)
|
||||||
call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len.2, i1 false)
|
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %len.2, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memset_and_memmove_different_size_values_2(i8* noalias %src, i8* noalias %dst, i64 %len.1) {
|
define void @memset_and_memmove_different_size_values_2(ptr noalias %src, ptr noalias %dst, i64 %len.1) {
|
||||||
; CHECK-LABEL: @memset_and_memmove_different_size_values_2(
|
; CHECK-LABEL: @memset_and_memmove_different_size_values_2(
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[DST:%.*]], i8 0, i64 [[LEN_1:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[DST:%.*]], i8 0, i64 [[LEN_1:%.*]], i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC:%.*]], i64 100, i1 false)
|
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr [[DST]], ptr [[SRC:%.*]], i64 100, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %dst, i8 0, i64 %len.1, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 0, i64 %len.1, i1 false)
|
||||||
call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 100, i1 false)
|
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 100, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memset_and_memmove_different_size_values_3(i8* noalias %src, i8* noalias %dst, i64 %len.1) {
|
define void @memset_and_memmove_different_size_values_3(ptr noalias %src, ptr noalias %dst, i64 %len.1) {
|
||||||
; CHECK-LABEL: @memset_and_memmove_different_size_values_3(
|
; CHECK-LABEL: @memset_and_memmove_different_size_values_3(
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[DST:%.*]], i8 0, i64 100, i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[DST:%.*]], i8 0, i64 100, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC:%.*]], i64 [[LEN_1:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr [[DST]], ptr [[SRC:%.*]], i64 [[LEN_1:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %dst, i8 0, i64 100, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 0, i64 100, i1 false)
|
||||||
call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len.1, i1 false)
|
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %len.1, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memmove_and_memset_equal_size_values(i8* noalias %src, i8* noalias %dst, i64 %len) {
|
define void @memmove_and_memset_equal_size_values(ptr noalias %src, ptr noalias %dst, i64 %len) {
|
||||||
; CHECK-LABEL: @memmove_and_memset_equal_size_values(
|
; CHECK-LABEL: @memmove_and_memset_equal_size_values(
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[DST:%.*]], i8 0, i64 [[LEN:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[DST:%.*]], i8 0, i64 [[LEN:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len, i1 false)
|
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %dst, i8 0, i64 %len, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 0, i64 %len, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memmove_and_memset_different_size_values_1(i8* noalias %src, i8* noalias %dst, i64 %len.1, i64 %len.2) {
|
define void @memmove_and_memset_different_size_values_1(ptr noalias %src, ptr noalias %dst, i64 %len.1, i64 %len.2) {
|
||||||
; CHECK-LABEL: @memmove_and_memset_different_size_values_1(
|
; CHECK-LABEL: @memmove_and_memset_different_size_values_1(
|
||||||
; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[LEN_1:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 [[LEN_1:%.*]], i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[DST]], i8 0, i64 [[LEN_2:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[DST]], i8 0, i64 [[LEN_2:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len.1, i1 false)
|
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %len.1, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %dst, i8 0, i64 %len.2, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 0, i64 %len.2, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memmove_and_memset_different_size_values_2(i8* noalias %src, i8* noalias %dst, i64 %len.1) {
|
define void @memmove_and_memset_different_size_values_2(ptr noalias %src, ptr noalias %dst, i64 %len.1) {
|
||||||
; CHECK-LABEL: @memmove_and_memset_different_size_values_2(
|
; CHECK-LABEL: @memmove_and_memset_different_size_values_2(
|
||||||
; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[LEN_1:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 [[LEN_1:%.*]], i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[DST]], i8 0, i64 100, i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[DST]], i8 0, i64 100, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len.1, i1 false)
|
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %len.1, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %dst, i8 0, i64 100, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 0, i64 100, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memmove_and_memset_different_size_values_3(i8* noalias %src, i8* noalias %dst, i64 %len.1) {
|
define void @memmove_and_memset_different_size_values_3(ptr noalias %src, ptr noalias %dst, i64 %len.1) {
|
||||||
; CHECK-LABEL: @memmove_and_memset_different_size_values_3(
|
; CHECK-LABEL: @memmove_and_memset_different_size_values_3(
|
||||||
; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 100, i1 false)
|
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 100, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[DST]], i8 0, i64 [[LEN_1:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[DST]], i8 0, i64 [[LEN_1:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 100, i1 false)
|
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 100, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 1 %dst, i8 0, i64 %len.1, i1 false)
|
call void @llvm.memset.p0.i64(ptr align 1 %dst, i8 0, i64 %len.1, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memmove_and_memcpy_equal_size_values(i8* noalias %src, i8* noalias %dst, i64 %len) {
|
define void @memmove_and_memcpy_equal_size_values(ptr noalias %src, ptr noalias %dst, i64 %len) {
|
||||||
; CHECK-LABEL: @memmove_and_memcpy_equal_size_values(
|
; CHECK-LABEL: @memmove_and_memcpy_equal_size_values(
|
||||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len, i1 false)
|
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @memcpy_and_memmove_equal_size_values(i8* noalias %src, i8* noalias %dst, i64 %len) {
|
define void @memcpy_and_memmove_equal_size_values(ptr noalias %src, ptr noalias %dst, i64 %len) {
|
||||||
; CHECK-LABEL: @memcpy_and_memmove_equal_size_values(
|
; CHECK-LABEL: @memcpy_and_memmove_equal_size_values(
|
||||||
; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
|
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 [[LEN:%.*]], i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len, i1 false)
|
call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
|
||||||
call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %len, i1 false)
|
call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %len, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg)
|
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg)
|
||||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1)
|
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1)
|
||||||
declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1)
|
declare void @llvm.memmove.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1)
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||||
|
|
||||||
|
|
||||||
define void @test2(i32* noalias %P, i32* noalias %Q, i32* noalias %R) {
|
define void @test2(ptr noalias %P, ptr noalias %Q, ptr noalias %R) {
|
||||||
; NO-LIMIT-LABEL: @test2(
|
; NO-LIMIT-LABEL: @test2(
|
||||||
; NO-LIMIT-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; NO-LIMIT-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; NO-LIMIT: bb1:
|
; NO-LIMIT: bb1:
|
||||||
|
@ -16,35 +16,35 @@ define void @test2(i32* noalias %P, i32* noalias %Q, i32* noalias %R) {
|
||||||
; NO-LIMIT: bb2:
|
; NO-LIMIT: bb2:
|
||||||
; NO-LIMIT-NEXT: br label [[BB3]]
|
; NO-LIMIT-NEXT: br label [[BB3]]
|
||||||
; NO-LIMIT: bb3:
|
; NO-LIMIT: bb3:
|
||||||
; NO-LIMIT-NEXT: store i32 0, i32* [[Q:%.*]], align 4
|
; NO-LIMIT-NEXT: store i32 0, ptr [[Q:%.*]], align 4
|
||||||
; NO-LIMIT-NEXT: store i32 0, i32* [[R:%.*]], align 4
|
; NO-LIMIT-NEXT: store i32 0, ptr [[R:%.*]], align 4
|
||||||
; NO-LIMIT-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; NO-LIMIT-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; NO-LIMIT-NEXT: ret void
|
; NO-LIMIT-NEXT: ret void
|
||||||
;
|
;
|
||||||
; LIMIT-0-LABEL: @test2(
|
; LIMIT-0-LABEL: @test2(
|
||||||
; LIMIT-0-NEXT: store i32 1, i32* [[P:%.*]], align 4
|
; LIMIT-0-NEXT: store i32 1, ptr [[P:%.*]], align 4
|
||||||
; LIMIT-0-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; LIMIT-0-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; LIMIT-0: bb1:
|
; LIMIT-0: bb1:
|
||||||
; LIMIT-0-NEXT: br label [[BB3:%.*]]
|
; LIMIT-0-NEXT: br label [[BB3:%.*]]
|
||||||
; LIMIT-0: bb2:
|
; LIMIT-0: bb2:
|
||||||
; LIMIT-0-NEXT: br label [[BB3]]
|
; LIMIT-0-NEXT: br label [[BB3]]
|
||||||
; LIMIT-0: bb3:
|
; LIMIT-0: bb3:
|
||||||
; LIMIT-0-NEXT: store i32 0, i32* [[Q:%.*]], align 4
|
; LIMIT-0-NEXT: store i32 0, ptr [[Q:%.*]], align 4
|
||||||
; LIMIT-0-NEXT: store i32 0, i32* [[R:%.*]], align 4
|
; LIMIT-0-NEXT: store i32 0, ptr [[R:%.*]], align 4
|
||||||
; LIMIT-0-NEXT: store i32 0, i32* [[P]], align 4
|
; LIMIT-0-NEXT: store i32 0, ptr [[P]], align 4
|
||||||
; LIMIT-0-NEXT: ret void
|
; LIMIT-0-NEXT: ret void
|
||||||
;
|
;
|
||||||
; LIMIT-2-LABEL: @test2(
|
; LIMIT-2-LABEL: @test2(
|
||||||
; LIMIT-2-NEXT: store i32 1, i32* [[P:%.*]], align 4
|
; LIMIT-2-NEXT: store i32 1, ptr [[P:%.*]], align 4
|
||||||
; LIMIT-2-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; LIMIT-2-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; LIMIT-2: bb1:
|
; LIMIT-2: bb1:
|
||||||
; LIMIT-2-NEXT: br label [[BB3:%.*]]
|
; LIMIT-2-NEXT: br label [[BB3:%.*]]
|
||||||
; LIMIT-2: bb2:
|
; LIMIT-2: bb2:
|
||||||
; LIMIT-2-NEXT: br label [[BB3]]
|
; LIMIT-2-NEXT: br label [[BB3]]
|
||||||
; LIMIT-2: bb3:
|
; LIMIT-2: bb3:
|
||||||
; LIMIT-2-NEXT: store i32 0, i32* [[Q:%.*]], align 4
|
; LIMIT-2-NEXT: store i32 0, ptr [[Q:%.*]], align 4
|
||||||
; LIMIT-2-NEXT: store i32 0, i32* [[R:%.*]], align 4
|
; LIMIT-2-NEXT: store i32 0, ptr [[R:%.*]], align 4
|
||||||
; LIMIT-2-NEXT: store i32 0, i32* [[P]], align 4
|
; LIMIT-2-NEXT: store i32 0, ptr [[P]], align 4
|
||||||
; LIMIT-2-NEXT: ret void
|
; LIMIT-2-NEXT: ret void
|
||||||
;
|
;
|
||||||
; LIMIT-3-LABEL: @test2(
|
; LIMIT-3-LABEL: @test2(
|
||||||
|
@ -54,20 +54,20 @@ define void @test2(i32* noalias %P, i32* noalias %Q, i32* noalias %R) {
|
||||||
; LIMIT-3: bb2:
|
; LIMIT-3: bb2:
|
||||||
; LIMIT-3-NEXT: br label [[BB3]]
|
; LIMIT-3-NEXT: br label [[BB3]]
|
||||||
; LIMIT-3: bb3:
|
; LIMIT-3: bb3:
|
||||||
; LIMIT-3-NEXT: store i32 0, i32* [[Q:%.*]], align 4
|
; LIMIT-3-NEXT: store i32 0, ptr [[Q:%.*]], align 4
|
||||||
; LIMIT-3-NEXT: store i32 0, i32* [[R:%.*]], align 4
|
; LIMIT-3-NEXT: store i32 0, ptr [[R:%.*]], align 4
|
||||||
; LIMIT-3-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; LIMIT-3-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; LIMIT-3-NEXT: ret void
|
; LIMIT-3-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
store i32 0, i32* %Q
|
store i32 0, ptr %Q
|
||||||
store i32 0, i32* %R
|
store i32 0, ptr %R
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,119 +3,119 @@
|
||||||
; RUN: opt < %s -aa-pipeline=basic-aa -passes=dse -S | FileCheck %s
|
; RUN: opt < %s -aa-pipeline=basic-aa -passes=dse -S | FileCheck %s
|
||||||
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
|
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
|
||||||
|
|
||||||
declare void @llvm.memset.p0i8.i64(i8* 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
|
declare void @llvm.memset.element.unordered.atomic.p0.i64(ptr nocapture, i8, i64, i32) nounwind
|
||||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
|
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind
|
||||||
declare void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind
|
declare void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i32) nounwind
|
||||||
declare void @llvm.init.trampoline(i8*, i8*, i8*)
|
declare void @llvm.init.trampoline(ptr, ptr, ptr)
|
||||||
|
|
||||||
|
|
||||||
;; Overwrite of memset by memcpy.
|
;; Overwrite of memset by memcpy.
|
||||||
define void @test17(i8* %P, i8* noalias %Q) nounwind ssp {
|
define void @test17(ptr %P, ptr noalias %Q) nounwind ssp {
|
||||||
; CHECK-LABEL: @test17(
|
; CHECK-LABEL: @test17(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P:%.*]], i8* [[Q:%.*]], i64 12, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[P:%.*]], ptr [[Q:%.*]], i64 12, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 false)
|
tail call void @llvm.memset.p0.i64(ptr %P, i8 42, i64 8, i1 false)
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
;; Overwrite of memset by memcpy.
|
;; Overwrite of memset by memcpy.
|
||||||
define void @test17_atomic(i8* %P, i8* noalias %Q) nounwind ssp {
|
define void @test17_atomic(ptr %P, ptr noalias %Q) nounwind ssp {
|
||||||
; CHECK-LABEL: @test17_atomic(
|
; CHECK-LABEL: @test17_atomic(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
|
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i32 1)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 1 %P, i8 42, i64 8, i32 1)
|
tail call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 1 %P, i8 42, i64 8, i32 1)
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
;; Overwrite of memset by memcpy. Overwrite is stronger atomicity. We can
|
;; Overwrite of memset by memcpy. Overwrite is stronger atomicity. We can
|
||||||
;; remove the memset.
|
;; remove the memset.
|
||||||
define void @test17_atomic_weaker(i8* %P, i8* noalias %Q) nounwind ssp {
|
define void @test17_atomic_weaker(ptr %P, ptr noalias %Q) nounwind ssp {
|
||||||
; CHECK-LABEL: @test17_atomic_weaker(
|
; CHECK-LABEL: @test17_atomic_weaker(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
|
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i32 1)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memset.p0i8.i64(i8* align 1 %P, i8 42, i64 8, i1 false)
|
tail call void @llvm.memset.p0.i64(ptr align 1 %P, i8 42, i64 8, i1 false)
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
;; Overwrite of memset by memcpy. Overwrite is weaker atomicity. We can remove
|
;; Overwrite of memset by memcpy. Overwrite is weaker atomicity. We can remove
|
||||||
;; the memset.
|
;; the memset.
|
||||||
define void @test17_atomic_weaker_2(i8* %P, i8* noalias %Q) nounwind ssp {
|
define void @test17_atomic_weaker_2(ptr %P, ptr noalias %Q) nounwind ssp {
|
||||||
; CHECK-LABEL: @test17_atomic_weaker_2(
|
; CHECK-LABEL: @test17_atomic_weaker_2(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 1 %P, i8 42, i64 8, i32 1)
|
tail call void @llvm.memset.element.unordered.atomic.p0.i64(ptr align 1 %P, i8 42, i64 8, i32 1)
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Should not delete the volatile memset.
|
; Should not delete the volatile memset.
|
||||||
define void @test17v(i8* %P, i8* %Q) nounwind ssp {
|
define void @test17v(ptr %P, ptr %Q) nounwind ssp {
|
||||||
; CHECK-LABEL: @test17v(
|
; CHECK-LABEL: @test17v(
|
||||||
; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* [[P:%.*]], i8 42, i64 8, i1 true)
|
; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr [[P:%.*]], i8 42, i64 8, i1 true)
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P]], i8* [[Q:%.*]], i64 12, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[P]], ptr [[Q:%.*]], i64 12, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 true)
|
tail call void @llvm.memset.p0.i64(ptr %P, i8 42, i64 8, i1 true)
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; See PR11763 - LLVM allows memcpy's source and destination to be equal (but not
|
; See PR11763 - LLVM allows memcpy's source and destination to be equal (but not
|
||||||
; inequal and overlapping).
|
; inequal and overlapping).
|
||||||
define void @test18(i8* %P, i8* %Q, i8* %R) nounwind ssp {
|
define void @test18(ptr %P, ptr %Q, ptr %R) nounwind ssp {
|
||||||
; CHECK-LABEL: @test18(
|
; CHECK-LABEL: @test18(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P:%.*]], i8* [[Q:%.*]], i64 12, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[P:%.*]], ptr [[Q:%.*]], i64 12, i1 false)
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[P]], i8* [[R:%.*]], i64 12, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[P]], ptr [[R:%.*]], i64 12, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %Q, i64 12, i1 false)
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr %P, ptr %R, i64 12, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test18_atomic(i8* %P, i8* %Q, i8* %R) nounwind ssp {
|
define void @test18_atomic(ptr %P, ptr %Q, ptr %R) nounwind ssp {
|
||||||
; CHECK-LABEL: @test18_atomic(
|
; CHECK-LABEL: @test18_atomic(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i32 1)
|
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i32 1)
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[R:%.*]], i64 12, i32 1)
|
; CHECK-NEXT: tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 [[P]], ptr align 1 [[R:%.*]], i64 12, i32 1)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i32 1)
|
||||||
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %R, i64 12, i32 1)
|
tail call void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr align 1 %P, ptr align 1 %R, i64 12, i32 1)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test_memset_memcpy_inline(i8* noalias %P, i8* noalias %Q) {
|
define void @test_memset_memcpy_inline(ptr noalias %P, ptr noalias %Q) {
|
||||||
; CHECK-LABEL: @test_memset_memcpy_inline(
|
; CHECK-LABEL: @test_memset_memcpy_inline(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.inline.p0i8.p0i8.i64(i8* align 1 [[P:%.*]], i8* align 1 [[Q:%.*]], i64 12, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.inline.p0.p0.i64(ptr align 1 [[P:%.*]], ptr align 1 [[Q:%.*]], i64 12, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 false)
|
tail call void @llvm.memset.p0.i64(ptr %P, i8 42, i64 8, i1 false)
|
||||||
tail call void @llvm.memcpy.inline.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i1 false)
|
tail call void @llvm.memcpy.inline.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 12, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test_store_memcpy_inline(i8* noalias %P, i8* noalias %Q) {
|
define void @test_store_memcpy_inline(ptr noalias %P, ptr noalias %Q) {
|
||||||
; CHECK-LABEL: @test_store_memcpy_inline(
|
; CHECK-LABEL: @test_store_memcpy_inline(
|
||||||
; CHECK-NEXT: [[P_4:%.*]] = getelementptr i8, i8* [[P:%.*]], i64 4
|
; CHECK-NEXT: [[P_4:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 4
|
||||||
; CHECK-NEXT: store i8 4, i8* [[P_4]], align 1
|
; CHECK-NEXT: store i8 4, ptr [[P_4]], align 1
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.inline.p0i8.p0i8.i64(i8* align 1 [[P]], i8* align 1 [[Q:%.*]], i64 4, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.inline.p0.p0.i64(ptr align 1 [[P]], ptr align 1 [[Q:%.*]], i64 4, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i8 0, i8* %P
|
store i8 0, ptr %P
|
||||||
%P.1 = getelementptr i8, i8* %P, i64 1
|
%P.1 = getelementptr i8, ptr %P, i64 1
|
||||||
store i8 1, i8* %P.1
|
store i8 1, ptr %P.1
|
||||||
%P.4 = getelementptr i8, i8* %P, i64 4
|
%P.4 = getelementptr i8, ptr %P, i64 4
|
||||||
store i8 4, i8* %P.4
|
store i8 4, ptr %P.4
|
||||||
tail call void @llvm.memcpy.inline.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 4, i1 false)
|
tail call void @llvm.memcpy.inline.p0.p0.i64(ptr align 1 %P, ptr align 1 %Q, i64 4, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.memcpy.inline.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64 immarg, i1 immarg)
|
declare void @llvm.memcpy.inline.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64 immarg, i1 immarg)
|
||||||
|
|
|
@ -3,9 +3,8 @@
|
||||||
; a memset can be shortened has the debugloc carried over from the memset.
|
; a memset can be shortened has the debugloc carried over from the memset.
|
||||||
|
|
||||||
; RUN: opt -S -march=native -dse < %s| FileCheck %s
|
; RUN: opt -S -march=native -dse < %s| FileCheck %s
|
||||||
; CHECK: bitcast [5 x i64]* %{{[a-zA-Z_][a-zA-Z0-9_]*}} to i8*, !dbg
|
; CHECK: %{{[0-9]+}} = getelementptr inbounds i8, ptr %b, i64 32, !dbg ![[DBG:[0-9]+]]
|
||||||
; CHECK-NEXT: %{{[0-9]+}} = getelementptr inbounds i8, i8* %0, i64 32, !dbg ![[DBG:[0-9]+]]
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 %0, i8 0, i64 8, i1 false), !dbg ![[DBG:[0-9]+]]
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 16 %1, i8 0, i64 8, i1 false), !dbg ![[DBG:[0-9]+]]
|
|
||||||
; CHECK: ![[DBG]] = !DILocation(line: 2,
|
; CHECK: ![[DBG]] = !DILocation(line: 2,
|
||||||
|
|
||||||
; The test IR is generated by running:
|
; The test IR is generated by running:
|
||||||
|
@ -23,25 +22,22 @@
|
||||||
; }
|
; }
|
||||||
|
|
||||||
|
|
||||||
declare void @use([5 x i64]*)
|
declare void @use(ptr)
|
||||||
|
|
||||||
define dso_local i32 @_Z1av() !dbg !7 {
|
define dso_local i32 @_Z1av() !dbg !7 {
|
||||||
entry:
|
entry:
|
||||||
%retval = alloca i32, align 4
|
%retval = alloca i32, align 4
|
||||||
%b = alloca [5 x i64], align 16
|
%b = alloca [5 x i64], align 16
|
||||||
call void @llvm.dbg.declare(metadata [5 x i64]* %b, metadata !11, metadata !DIExpression()), !dbg !16
|
call void @llvm.dbg.declare(metadata ptr %b, metadata !11, metadata !DIExpression()), !dbg !16
|
||||||
%0 = bitcast [5 x i64]* %b to i8*, !dbg !16
|
call void @llvm.memset.p0.i64(ptr align 16 %b, i8 0, i64 40, i1 false), !dbg !16
|
||||||
call void @llvm.memset.p0i8.i64(i8* align 16 %0, i8 0, i64 40, i1 false), !dbg !16
|
store i64 2, ptr %b, align 16, !dbg !16
|
||||||
%1 = bitcast i8* %0 to [5 x i64]*, !dbg !16
|
%0 = getelementptr inbounds [5 x i64], ptr %b, i32 0, i32 1, !dbg !16
|
||||||
%2 = getelementptr inbounds [5 x i64], [5 x i64]* %1, i32 0, i32 0, !dbg !16
|
store i64 2, ptr %0, align 8, !dbg !16
|
||||||
store i64 2, i64* %2, align 16, !dbg !16
|
%1 = getelementptr inbounds [5 x i64], ptr %b, i32 0, i32 2, !dbg !16
|
||||||
%3 = getelementptr inbounds [5 x i64], [5 x i64]* %1, i32 0, i32 1, !dbg !16
|
store i64 2, ptr %1, align 16, !dbg !16
|
||||||
store i64 2, i64* %3, align 8, !dbg !16
|
%2 = getelementptr inbounds [5 x i64], ptr %b, i32 0, i32 3, !dbg !16
|
||||||
%4 = getelementptr inbounds [5 x i64], [5 x i64]* %1, i32 0, i32 2, !dbg !16
|
store i64 2, ptr %2, align 8, !dbg !16
|
||||||
store i64 2, i64* %4, align 16, !dbg !16
|
call void @use(ptr %b)
|
||||||
%5 = getelementptr inbounds [5 x i64], [5 x i64]* %1, i32 0, i32 3, !dbg !16
|
|
||||||
store i64 2, i64* %5, align 8, !dbg !16
|
|
||||||
call void @use([5 x i64]* %b)
|
|
||||||
%call = call i32 @_Z1av(), !dbg !17
|
%call = call i32 @_Z1av(), !dbg !17
|
||||||
%tobool = icmp ne i32 %call, 0, !dbg !17
|
%tobool = icmp ne i32 %call, 0, !dbg !17
|
||||||
br i1 %tobool, label %if.then, label %if.end, !dbg !19
|
br i1 %tobool, label %if.then, label %if.end, !dbg !19
|
||||||
|
@ -54,15 +50,15 @@ if.end: ; preds = %if.then, %entry
|
||||||
unreachable, !dbg !20
|
unreachable, !dbg !20
|
||||||
|
|
||||||
return: ; No predecessors!
|
return: ; No predecessors!
|
||||||
%6 = load i32, i32* %retval, align 4, !dbg !21
|
%3 = load i32, ptr %retval, align 4, !dbg !21
|
||||||
ret i32 %6, !dbg !21
|
ret i32 %3, !dbg !21
|
||||||
}
|
}
|
||||||
|
|
||||||
; Function Attrs: nounwind readnone speculatable
|
; Function Attrs: nounwind readnone speculatable
|
||||||
declare void @llvm.dbg.declare(metadata, metadata, metadata)
|
declare void @llvm.dbg.declare(metadata, metadata, metadata)
|
||||||
|
|
||||||
; Function Attrs: argmemonly nounwind
|
; Function Attrs: argmemonly nounwind
|
||||||
declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg)
|
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg)
|
||||||
|
|
||||||
; Function Attrs: cold noreturn nounwind
|
; Function Attrs: cold noreturn nounwind
|
||||||
declare void @llvm.trap()
|
declare void @llvm.trap()
|
||||||
|
|
|
@ -1,68 +1,64 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||||
; RUN: opt -dse -S %s | FileCheck %s
|
; RUN: opt -dse -S %s | FileCheck %s
|
||||||
|
|
||||||
declare i8* @_Znwm() local_unnamed_addr #0
|
declare ptr @_Znwm() local_unnamed_addr #0
|
||||||
|
|
||||||
; Function Attrs: argmemonly nounwind willreturn writeonly
|
; Function Attrs: argmemonly nounwind willreturn writeonly
|
||||||
declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #1
|
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #1
|
||||||
|
|
||||||
define i8* @test1(i1 %c, i64 %N) {
|
define ptr @test1(i1 %c, i64 %N) {
|
||||||
; CHECK-LABEL: @test1(
|
; CHECK-LABEL: @test1(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[COND_TRUE_I_I_I:%.*]], label [[COND_END_I_I_I:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[COND_TRUE_I_I_I:%.*]], label [[COND_END_I_I_I:%.*]]
|
||||||
; CHECK: cond.true.i.i.i:
|
; CHECK: cond.true.i.i.i:
|
||||||
; CHECK-NEXT: ret i8* null
|
; CHECK-NEXT: ret ptr null
|
||||||
; CHECK: cond.end.i.i.i:
|
; CHECK: cond.end.i.i.i:
|
||||||
; CHECK-NEXT: [[ALLOC:%.*]] = tail call noalias nonnull i8* @_Znam() #[[ATTR2:[0-9]+]]
|
; CHECK-NEXT: [[ALLOC:%.*]] = tail call noalias nonnull ptr @_Znam() #[[ATTR2:[0-9]+]]
|
||||||
; CHECK-NEXT: [[ALLOC_BC:%.*]] = bitcast i8* [[ALLOC]] to i64*
|
; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr nonnull align 8 [[ALLOC]], i8 0, i64 [[N:%.*]], i1 false) #[[ATTR3:[0-9]+]]
|
||||||
; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* nonnull align 8 [[ALLOC]], i8 0, i64 [[N:%.*]], i1 false) #[[ATTR3:[0-9]+]]
|
; CHECK-NEXT: store i64 0, ptr [[ALLOC]], align 8
|
||||||
; CHECK-NEXT: store i64 0, i64* [[ALLOC_BC]], align 8
|
; CHECK-NEXT: ret ptr [[ALLOC]]
|
||||||
; CHECK-NEXT: ret i8* [[ALLOC]]
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
br i1 %c, label %cond.true.i.i.i, label %cond.end.i.i.i
|
br i1 %c, label %cond.true.i.i.i, label %cond.end.i.i.i
|
||||||
|
|
||||||
cond.true.i.i.i: ; preds = %entry
|
cond.true.i.i.i: ; preds = %entry
|
||||||
ret i8* null
|
ret ptr null
|
||||||
|
|
||||||
cond.end.i.i.i: ; preds = %entry
|
cond.end.i.i.i: ; preds = %entry
|
||||||
%alloc = tail call noalias nonnull i8* @_Znam() #2
|
%alloc = tail call noalias nonnull ptr @_Znam() #2
|
||||||
%alloc.bc = bitcast i8* %alloc to i64*
|
tail call void @llvm.memset.p0.i64(ptr nonnull align 8 %alloc, i8 0, i64 %N, i1 false) #3
|
||||||
tail call void @llvm.memset.p0i8.i64(i8* nonnull align 8 %alloc, i8 0, i64 %N, i1 false) #3
|
store i64 0, ptr %alloc, align 8
|
||||||
store i64 0, i64* %alloc.bc, align 8
|
ret ptr %alloc
|
||||||
ret i8* %alloc
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i8* @_Znam()
|
declare ptr @_Znam()
|
||||||
|
|
||||||
|
|
||||||
define i8* @test2(i1 %c, i64 %N) {
|
define ptr @test2(i1 %c, i64 %N) {
|
||||||
; CHECK-LABEL: @test2(
|
; CHECK-LABEL: @test2(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[CLEANUP_CONT104:%.*]], label [[IF_THEN:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[CLEANUP_CONT104:%.*]], label [[IF_THEN:%.*]]
|
||||||
; CHECK: if.then:
|
; CHECK: if.then:
|
||||||
; CHECK-NEXT: [[MUL:%.*]] = shl nuw nsw i64 [[N:%.*]], 3
|
; CHECK-NEXT: [[MUL:%.*]] = shl nuw nsw i64 [[N:%.*]], 3
|
||||||
; CHECK-NEXT: [[ALLOC:%.*]] = call noalias nonnull i8* @_Znwm() #[[ATTR2]]
|
; CHECK-NEXT: [[ALLOC:%.*]] = call noalias nonnull ptr @_Znwm() #[[ATTR2]]
|
||||||
; CHECK-NEXT: [[ALLOC_BC:%.*]] = bitcast i8* [[ALLOC]] to i64*
|
; CHECK-NEXT: store i64 0, ptr [[ALLOC]], align 8
|
||||||
; CHECK-NEXT: store i64 0, i64* [[ALLOC_BC]], align 8
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr nonnull align 8 [[ALLOC]], i8 0, i64 [[MUL]], i1 false) #[[ATTR3]]
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 8 [[ALLOC]], i8 0, i64 [[MUL]], i1 false) #[[ATTR3]]
|
; CHECK-NEXT: ret ptr [[ALLOC]]
|
||||||
; CHECK-NEXT: ret i8* [[ALLOC]]
|
|
||||||
; CHECK: cleanup.cont104:
|
; CHECK: cleanup.cont104:
|
||||||
; CHECK-NEXT: ret i8* null
|
; CHECK-NEXT: ret ptr null
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
br i1 %c, label %cleanup.cont104, label %if.then
|
br i1 %c, label %cleanup.cont104, label %if.then
|
||||||
|
|
||||||
if.then: ; preds = %entry
|
if.then: ; preds = %entry
|
||||||
%mul = shl nuw nsw i64 %N, 3
|
%mul = shl nuw nsw i64 %N, 3
|
||||||
%alloc = call noalias nonnull i8* @_Znwm() #2
|
%alloc = call noalias nonnull ptr @_Znwm() #2
|
||||||
%alloc.bc = bitcast i8* %alloc to i64*
|
store i64 0, ptr %alloc, align 8
|
||||||
store i64 0, i64* %alloc.bc, align 8
|
call void @llvm.memset.p0.i64(ptr nonnull align 8 %alloc, i8 0, i64 %mul, i1 false) #3
|
||||||
call void @llvm.memset.p0i8.i64(i8* nonnull align 8 %alloc, i8 0, i64 %mul, i1 false) #3
|
ret ptr %alloc
|
||||||
ret i8* %alloc
|
|
||||||
|
|
||||||
cleanup.cont104: ; preds = %entry
|
cleanup.cont104: ; preds = %entry
|
||||||
ret i8* null
|
ret ptr null
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes #0 = { "use-soft-float"="false" }
|
attributes #0 = { "use-soft-float"="false" }
|
||||||
|
|
|
@ -2,153 +2,136 @@
|
||||||
; RUN: opt -dse -enable-dse-partial-store-merging -S < %s | FileCheck %s
|
; RUN: opt -dse -enable-dse-partial-store-merging -S < %s | FileCheck %s
|
||||||
target datalayout = "E-m:e-i64:64-i128:128-n32:64-S128"
|
target datalayout = "E-m:e-i64:64-i128:128-n32:64-S128"
|
||||||
|
|
||||||
define void @byte_by_byte_replacement(i32 *%ptr) {
|
define void @byte_by_byte_replacement(ptr %ptr) {
|
||||||
; CHECK-LABEL: @byte_by_byte_replacement(
|
; CHECK-LABEL: @byte_by_byte_replacement(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i32 151653132, i32* [[PTR:%.*]]
|
; CHECK-NEXT: store i32 151653132, ptr [[PTR:%.*]]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
;; This store's value should be modified as it should be better to use one
|
;; This store's value should be modified as it should be better to use one
|
||||||
;; larger store than several smaller ones.
|
;; larger store than several smaller ones.
|
||||||
;; store will turn into 0x090A0B0C == 151653132
|
;; store will turn into 0x090A0B0C == 151653132
|
||||||
store i32 305419896, i32* %ptr ; 0x12345678
|
store i32 305419896, ptr %ptr ; 0x12345678
|
||||||
%bptr = bitcast i32* %ptr to i8*
|
%bptr1 = getelementptr inbounds i8, ptr %ptr, i64 1
|
||||||
%bptr1 = getelementptr inbounds i8, i8* %bptr, i64 1
|
%bptr2 = getelementptr inbounds i8, ptr %ptr, i64 2
|
||||||
%bptr2 = getelementptr inbounds i8, i8* %bptr, i64 2
|
%bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
||||||
%bptr3 = getelementptr inbounds i8, i8* %bptr, i64 3
|
|
||||||
|
|
||||||
;; We should be able to merge these four stores with the i32 above
|
;; We should be able to merge these four stores with the i32 above
|
||||||
; value (and bytes) stored before ; 0x12345678
|
; value (and bytes) stored before ; 0x12345678
|
||||||
store i8 9, i8* %bptr ; 09
|
store i8 9, ptr %ptr ; 09
|
||||||
store i8 10, i8* %bptr1 ; 0A
|
store i8 10, ptr %bptr1 ; 0A
|
||||||
store i8 11, i8* %bptr2 ; 0B
|
store i8 11, ptr %bptr2 ; 0B
|
||||||
store i8 12, i8* %bptr3 ; 0C
|
store i8 12, ptr %bptr3 ; 0C
|
||||||
; 0x090A0B0C
|
; 0x090A0B0C
|
||||||
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @word_replacement(i64 *%ptr) {
|
define void @word_replacement(ptr %ptr) {
|
||||||
; CHECK-LABEL: @word_replacement(
|
; CHECK-LABEL: @word_replacement(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i64 72638273700655232, i64* [[PTR:%.*]]
|
; CHECK-NEXT: store i64 72638273700655232, ptr [[PTR:%.*]]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i64 72623859790382856, i64* %ptr ; 0x0102030405060708
|
store i64 72623859790382856, ptr %ptr ; 0x0102030405060708
|
||||||
|
|
||||||
%wptr = bitcast i64* %ptr to i16*
|
%wptr1 = getelementptr inbounds i16, ptr %ptr, i64 1
|
||||||
%wptr1 = getelementptr inbounds i16, i16* %wptr, i64 1
|
%wptr3 = getelementptr inbounds i16, ptr %ptr, i64 3
|
||||||
%wptr3 = getelementptr inbounds i16, i16* %wptr, i64 3
|
|
||||||
|
|
||||||
;; We should be able to merge these two stores with the i64 one above
|
;; We should be able to merge these two stores with the i64 one above
|
||||||
; value (and bytes) stored before ; 0x0102030405060708
|
; value (and bytes) stored before ; 0x0102030405060708
|
||||||
store i16 4128, i16* %wptr1 ; 1020
|
store i16 4128, ptr %wptr1 ; 1020
|
||||||
store i16 28800, i16* %wptr3 ; 7080
|
store i16 28800, ptr %wptr3 ; 7080
|
||||||
; 0x0102102005067080
|
; 0x0102102005067080
|
||||||
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
define void @differently_sized_replacements(i64 *%ptr) {
|
define void @differently_sized_replacements(ptr %ptr) {
|
||||||
; CHECK-LABEL: @differently_sized_replacements(
|
; CHECK-LABEL: @differently_sized_replacements(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i64 289077004501059343, i64* [[PTR:%.*]]
|
; CHECK-NEXT: store i64 289077004501059343, ptr [[PTR:%.*]]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i64 579005069656919567, i64* %ptr ; 0x08090a0b0c0d0e0f
|
store i64 579005069656919567, ptr %ptr ; 0x08090a0b0c0d0e0f
|
||||||
|
|
||||||
%bptr = bitcast i64* %ptr to i8*
|
%bptr6 = getelementptr inbounds i8, ptr %ptr, i64 6
|
||||||
%bptr6 = getelementptr inbounds i8, i8* %bptr, i64 6
|
%wptr2 = getelementptr inbounds i16, ptr %ptr, i64 2
|
||||||
%wptr = bitcast i64* %ptr to i16*
|
|
||||||
%wptr2 = getelementptr inbounds i16, i16* %wptr, i64 2
|
|
||||||
%dptr = bitcast i64* %ptr to i32*
|
|
||||||
|
|
||||||
;; We should be able to merge all these stores with the i64 one above
|
;; We should be able to merge all these stores with the i64 one above
|
||||||
; value (and bytes) stored before ; 0x08090a0b0c0d0e0f
|
; value (and bytes) stored before ; 0x08090a0b0c0d0e0f
|
||||||
store i8 7, i8* %bptr6 ; 07
|
store i8 7, ptr %bptr6 ; 07
|
||||||
store i16 1541, i16* %wptr2 ; 0605
|
store i16 1541, ptr %wptr2 ; 0605
|
||||||
store i32 67305985, i32* %dptr ; 04030201
|
store i32 67305985, ptr %ptr ; 04030201
|
||||||
; 0x040302010605070f
|
; 0x040302010605070f
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
define void @multiple_replacements_to_same_byte(i64 *%ptr) {
|
define void @multiple_replacements_to_same_byte(ptr %ptr) {
|
||||||
; CHECK-LABEL: @multiple_replacements_to_same_byte(
|
; CHECK-LABEL: @multiple_replacements_to_same_byte(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i64 289077004602248719, i64* [[PTR:%.*]]
|
; CHECK-NEXT: store i64 289077004602248719, ptr [[PTR:%.*]]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i64 579005069656919567, i64* %ptr ; 0x08090a0b0c0d0e0f
|
store i64 579005069656919567, ptr %ptr ; 0x08090a0b0c0d0e0f
|
||||||
|
|
||||||
%bptr = bitcast i64* %ptr to i8*
|
%bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
||||||
%bptr3 = getelementptr inbounds i8, i8* %bptr, i64 3
|
%wptr1 = getelementptr inbounds i16, ptr %ptr, i64 1
|
||||||
%wptr = bitcast i64* %ptr to i16*
|
|
||||||
%wptr1 = getelementptr inbounds i16, i16* %wptr, i64 1
|
|
||||||
%dptr = bitcast i64* %ptr to i32*
|
|
||||||
|
|
||||||
;; We should be able to merge all these stores with the i64 one above
|
;; We should be able to merge all these stores with the i64 one above
|
||||||
; value (and bytes) stored before ; 0x08090a0b0c0d0e0f
|
; value (and bytes) stored before ; 0x08090a0b0c0d0e0f
|
||||||
store i8 7, i8* %bptr3 ; 07
|
store i8 7, ptr %bptr3 ; 07
|
||||||
store i16 1541, i16* %wptr1 ; 0605
|
store i16 1541, ptr %wptr1 ; 0605
|
||||||
store i32 67305985, i32* %dptr ; 04030201
|
store i32 67305985, ptr %ptr ; 04030201
|
||||||
; 0x040302010c0d0e0f
|
; 0x040302010c0d0e0f
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @merged_merges(i64 *%ptr) {
|
define void @merged_merges(ptr %ptr) {
|
||||||
; CHECK-LABEL: @merged_merges(
|
; CHECK-LABEL: @merged_merges(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i64 289081428418563599, i64* [[PTR:%.*]]
|
; CHECK-NEXT: store i64 289081428418563599, ptr [[PTR:%.*]]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i64 579005069656919567, i64* %ptr ; 0x08090a0b0c0d0e0f
|
store i64 579005069656919567, ptr %ptr ; 0x08090a0b0c0d0e0f
|
||||||
|
|
||||||
%bptr = bitcast i64* %ptr to i8*
|
%bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
||||||
%bptr3 = getelementptr inbounds i8, i8* %bptr, i64 3
|
%wptr1 = getelementptr inbounds i16, ptr %ptr, i64 1
|
||||||
%wptr = bitcast i64* %ptr to i16*
|
|
||||||
%wptr1 = getelementptr inbounds i16, i16* %wptr, i64 1
|
|
||||||
%dptr = bitcast i64* %ptr to i32*
|
|
||||||
|
|
||||||
;; We should be able to merge all these stores with the i64 one above
|
;; We should be able to merge all these stores with the i64 one above
|
||||||
; value (not bytes) stored before ; 0x08090a0b0c0d0e0f
|
; value (not bytes) stored before ; 0x08090a0b0c0d0e0f
|
||||||
store i32 67305985, i32* %dptr ; 04030201
|
store i32 67305985, ptr %ptr ; 04030201
|
||||||
store i16 1541, i16* %wptr1 ; 0605
|
store i16 1541, ptr %wptr1 ; 0605
|
||||||
store i8 7, i8* %bptr3 ; 07
|
store i8 7, ptr %bptr3 ; 07
|
||||||
; 0x040306070c0d0e0f
|
; 0x040306070c0d0e0f
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define signext i8 @shouldnt_merge_since_theres_a_full_overlap(i64 *%ptr) {
|
define signext i8 @shouldnt_merge_since_theres_a_full_overlap(ptr %ptr) {
|
||||||
; CHECK-LABEL: @shouldnt_merge_since_theres_a_full_overlap(
|
; CHECK-LABEL: @shouldnt_merge_since_theres_a_full_overlap(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[BPTR:%.*]] = bitcast i64* [[PTR:%.*]] to i8*
|
; CHECK-NEXT: [[BPTRM1:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 -1
|
||||||
; CHECK-NEXT: [[BPTRM1:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 -1
|
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 3
|
||||||
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 3
|
; CHECK-NEXT: store i32 1234, ptr [[BPTRM1]], align 1
|
||||||
; CHECK-NEXT: [[DPTR:%.*]] = bitcast i8* [[BPTRM1]] to i32*
|
; CHECK-NEXT: store i64 5678, ptr [[BPTR3]], align 1
|
||||||
; CHECK-NEXT: [[QPTR:%.*]] = bitcast i8* [[BPTR3]] to i64*
|
|
||||||
; CHECK-NEXT: store i32 1234, i32* [[DPTR]], align 1
|
|
||||||
; CHECK-NEXT: store i64 5678, i64* [[QPTR]], align 1
|
|
||||||
; CHECK-NEXT: ret i8 0
|
; CHECK-NEXT: ret i8 0
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
store i64 0, i64* %ptr
|
store i64 0, ptr %ptr
|
||||||
|
|
||||||
%bptr = bitcast i64* %ptr to i8*
|
%bptrm1 = getelementptr inbounds i8, ptr %ptr, i64 -1
|
||||||
%bptrm1 = getelementptr inbounds i8, i8* %bptr, i64 -1
|
%bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
||||||
%bptr3 = getelementptr inbounds i8, i8* %bptr, i64 3
|
|
||||||
%dptr = bitcast i8* %bptrm1 to i32*
|
|
||||||
%qptr = bitcast i8* %bptr3 to i64*
|
|
||||||
|
|
||||||
store i32 1234, i32* %dptr, align 1
|
store i32 1234, ptr %bptrm1, align 1
|
||||||
store i64 5678, i64* %qptr, align 1
|
store i64 5678, ptr %bptr3, align 1
|
||||||
|
|
||||||
ret i8 0
|
ret i8 0
|
||||||
}
|
}
|
||||||
|
@ -156,17 +139,14 @@ entry:
|
||||||
;; Test case from PR31777
|
;; Test case from PR31777
|
||||||
%union.U = type { i64 }
|
%union.U = type { i64 }
|
||||||
|
|
||||||
define void @foo(%union.U* nocapture %u) {
|
define void @foo(ptr nocapture %u) {
|
||||||
; CHECK-LABEL: @foo(
|
; CHECK-LABEL: @foo(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[I:%.*]] = getelementptr inbounds [[UNION_U:%.*]], %union.U* [[U:%.*]], i64 0, i32 0
|
; CHECK-NEXT: store i64 11821949021847552, ptr [[U:%.*]], align 8
|
||||||
; CHECK-NEXT: store i64 11821949021847552, i64* [[I]], align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%i = getelementptr inbounds %union.U, %union.U* %u, i64 0, i32 0
|
store i64 0, ptr %u, align 8
|
||||||
store i64 0, i64* %i, align 8
|
store i16 42, ptr %u, align 8
|
||||||
%s = bitcast %union.U* %u to i16*
|
|
||||||
store i16 42, i16* %s, align 8
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,152 +2,135 @@
|
||||||
; RUN: opt -dse -enable-dse-partial-store-merging -S < %s | FileCheck %s
|
; RUN: opt -dse -enable-dse-partial-store-merging -S < %s | FileCheck %s
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-f128:128:128-n8:16:32:64"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-f128:128:128-n8:16:32:64"
|
||||||
|
|
||||||
define void @byte_by_byte_replacement(i32 *%ptr) {
|
define void @byte_by_byte_replacement(ptr %ptr) {
|
||||||
; CHECK-LABEL: @byte_by_byte_replacement(
|
; CHECK-LABEL: @byte_by_byte_replacement(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i32 202050057, i32* [[PTR:%.*]]
|
; CHECK-NEXT: store i32 202050057, ptr [[PTR:%.*]]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
;; This store's value should be modified as it should be better to use one
|
;; This store's value should be modified as it should be better to use one
|
||||||
;; larger store than several smaller ones.
|
;; larger store than several smaller ones.
|
||||||
;; store will turn into 0x0C0B0A09 == 202050057
|
;; store will turn into 0x0C0B0A09 == 202050057
|
||||||
store i32 305419896, i32* %ptr ; 0x12345678
|
store i32 305419896, ptr %ptr ; 0x12345678
|
||||||
%bptr = bitcast i32* %ptr to i8*
|
%bptr1 = getelementptr inbounds i8, ptr %ptr, i64 1
|
||||||
%bptr1 = getelementptr inbounds i8, i8* %bptr, i64 1
|
%bptr2 = getelementptr inbounds i8, ptr %ptr, i64 2
|
||||||
%bptr2 = getelementptr inbounds i8, i8* %bptr, i64 2
|
%bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
||||||
%bptr3 = getelementptr inbounds i8, i8* %bptr, i64 3
|
|
||||||
|
|
||||||
;; We should be able to merge these four stores with the i32 above
|
;; We should be able to merge these four stores with the i32 above
|
||||||
; value (and bytes) stored before ; 0x12345678
|
; value (and bytes) stored before ; 0x12345678
|
||||||
store i8 9, i8* %bptr ; 09
|
store i8 9, ptr %ptr ; 09
|
||||||
store i8 10, i8* %bptr1 ; 0A
|
store i8 10, ptr %bptr1 ; 0A
|
||||||
store i8 11, i8* %bptr2 ; 0B
|
store i8 11, ptr %bptr2 ; 0B
|
||||||
store i8 12, i8* %bptr3 ; 0C
|
store i8 12, ptr %bptr3 ; 0C
|
||||||
; 0x0C0B0A09
|
; 0x0C0B0A09
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @word_replacement(i64 *%ptr) {
|
define void @word_replacement(ptr %ptr) {
|
||||||
; CHECK-LABEL: @word_replacement(
|
; CHECK-LABEL: @word_replacement(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i64 8106482645252179720, i64* [[PTR:%.*]]
|
; CHECK-NEXT: store i64 8106482645252179720, ptr [[PTR:%.*]]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i64 72623859790382856, i64* %ptr ; 0x0102030405060708
|
store i64 72623859790382856, ptr %ptr ; 0x0102030405060708
|
||||||
|
|
||||||
%wptr = bitcast i64* %ptr to i16*
|
%wptr1 = getelementptr inbounds i16, ptr %ptr, i64 1
|
||||||
%wptr1 = getelementptr inbounds i16, i16* %wptr, i64 1
|
%wptr3 = getelementptr inbounds i16, ptr %ptr, i64 3
|
||||||
%wptr3 = getelementptr inbounds i16, i16* %wptr, i64 3
|
|
||||||
|
|
||||||
;; We should be able to merge these two stores with the i64 one above
|
;; We should be able to merge these two stores with the i64 one above
|
||||||
; value (not bytes) stored before ; 0x0102030405060708
|
; value (not bytes) stored before ; 0x0102030405060708
|
||||||
store i16 4128, i16* %wptr1 ; 1020
|
store i16 4128, ptr %wptr1 ; 1020
|
||||||
store i16 28800, i16* %wptr3 ; 7080
|
store i16 28800, ptr %wptr3 ; 7080
|
||||||
; 0x7080030410200708
|
; 0x7080030410200708
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
define void @differently_sized_replacements(i64 *%ptr) {
|
define void @differently_sized_replacements(ptr %ptr) {
|
||||||
; CHECK-LABEL: @differently_sized_replacements(
|
; CHECK-LABEL: @differently_sized_replacements(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i64 578437695752307201, i64* [[PTR:%.*]]
|
; CHECK-NEXT: store i64 578437695752307201, ptr [[PTR:%.*]]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i64 579005069656919567, i64* %ptr ; 0x08090a0b0c0d0e0f
|
store i64 579005069656919567, ptr %ptr ; 0x08090a0b0c0d0e0f
|
||||||
|
|
||||||
%bptr = bitcast i64* %ptr to i8*
|
%bptr6 = getelementptr inbounds i8, ptr %ptr, i64 6
|
||||||
%bptr6 = getelementptr inbounds i8, i8* %bptr, i64 6
|
%wptr2 = getelementptr inbounds i16, ptr %ptr, i64 2
|
||||||
%wptr = bitcast i64* %ptr to i16*
|
|
||||||
%wptr2 = getelementptr inbounds i16, i16* %wptr, i64 2
|
|
||||||
%dptr = bitcast i64* %ptr to i32*
|
|
||||||
|
|
||||||
;; We should be able to merge all these stores with the i64 one above
|
;; We should be able to merge all these stores with the i64 one above
|
||||||
; value (not bytes) stored before ; 0x08090a0b0c0d0e0f
|
; value (not bytes) stored before ; 0x08090a0b0c0d0e0f
|
||||||
store i8 7, i8* %bptr6 ; 07
|
store i8 7, ptr %bptr6 ; 07
|
||||||
store i16 1541, i16* %wptr2 ; 0605
|
store i16 1541, ptr %wptr2 ; 0605
|
||||||
store i32 67305985, i32* %dptr ; 04030201
|
store i32 67305985, ptr %ptr ; 04030201
|
||||||
; 0x0807060504030201
|
; 0x0807060504030201
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
define void @multiple_replacements_to_same_byte(i64 *%ptr) {
|
define void @multiple_replacements_to_same_byte(ptr %ptr) {
|
||||||
; CHECK-LABEL: @multiple_replacements_to_same_byte(
|
; CHECK-LABEL: @multiple_replacements_to_same_byte(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i64 579005069522043393, i64* [[PTR:%.*]]
|
; CHECK-NEXT: store i64 579005069522043393, ptr [[PTR:%.*]]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i64 579005069656919567, i64* %ptr ; 0x08090a0b0c0d0e0f
|
store i64 579005069656919567, ptr %ptr ; 0x08090a0b0c0d0e0f
|
||||||
|
|
||||||
%bptr = bitcast i64* %ptr to i8*
|
%bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
||||||
%bptr3 = getelementptr inbounds i8, i8* %bptr, i64 3
|
%wptr1 = getelementptr inbounds i16, ptr %ptr, i64 1
|
||||||
%wptr = bitcast i64* %ptr to i16*
|
|
||||||
%wptr1 = getelementptr inbounds i16, i16* %wptr, i64 1
|
|
||||||
%dptr = bitcast i64* %ptr to i32*
|
|
||||||
|
|
||||||
;; We should be able to merge all these stores with the i64 one above
|
;; We should be able to merge all these stores with the i64 one above
|
||||||
; value (not bytes) stored before ; 0x08090a0b0c0d0e0f
|
; value (not bytes) stored before ; 0x08090a0b0c0d0e0f
|
||||||
store i8 7, i8* %bptr3 ; 07
|
store i8 7, ptr %bptr3 ; 07
|
||||||
store i16 1541, i16* %wptr1 ; 0605
|
store i16 1541, ptr %wptr1 ; 0605
|
||||||
store i32 67305985, i32* %dptr ; 04030201
|
store i32 67305985, ptr %ptr ; 04030201
|
||||||
; 0x08090a0b04030201
|
; 0x08090a0b04030201
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @merged_merges(i64 *%ptr) {
|
define void @merged_merges(ptr %ptr) {
|
||||||
; CHECK-LABEL: @merged_merges(
|
; CHECK-LABEL: @merged_merges(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i64 579005069572506113, i64* [[PTR:%.*]]
|
; CHECK-NEXT: store i64 579005069572506113, ptr [[PTR:%.*]]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i64 579005069656919567, i64* %ptr ; 0x08090a0b0c0d0e0f
|
store i64 579005069656919567, ptr %ptr ; 0x08090a0b0c0d0e0f
|
||||||
|
|
||||||
%bptr = bitcast i64* %ptr to i8*
|
%bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
||||||
%bptr3 = getelementptr inbounds i8, i8* %bptr, i64 3
|
%wptr1 = getelementptr inbounds i16, ptr %ptr, i64 1
|
||||||
%wptr = bitcast i64* %ptr to i16*
|
|
||||||
%wptr1 = getelementptr inbounds i16, i16* %wptr, i64 1
|
|
||||||
%dptr = bitcast i64* %ptr to i32*
|
|
||||||
|
|
||||||
;; We should be able to merge all these stores with the i64 one above
|
;; We should be able to merge all these stores with the i64 one above
|
||||||
; value (not bytes) stored before ; 0x08090a0b0c0d0e0f
|
; value (not bytes) stored before ; 0x08090a0b0c0d0e0f
|
||||||
store i32 67305985, i32* %dptr ; 04030201
|
store i32 67305985, ptr %ptr ; 04030201
|
||||||
store i16 1541, i16* %wptr1 ; 0605
|
store i16 1541, ptr %wptr1 ; 0605
|
||||||
store i8 7, i8* %bptr3 ; 07
|
store i8 7, ptr %bptr3 ; 07
|
||||||
; 0x08090a0b07050201
|
; 0x08090a0b07050201
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define signext i8 @shouldnt_merge_since_theres_a_full_overlap(i64 *%ptr) {
|
define signext i8 @shouldnt_merge_since_theres_a_full_overlap(ptr %ptr) {
|
||||||
; CHECK-LABEL: @shouldnt_merge_since_theres_a_full_overlap(
|
; CHECK-LABEL: @shouldnt_merge_since_theres_a_full_overlap(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[BPTR:%.*]] = bitcast i64* [[PTR:%.*]] to i8*
|
; CHECK-NEXT: [[BPTRM1:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 -1
|
||||||
; CHECK-NEXT: [[BPTRM1:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 -1
|
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 3
|
||||||
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 3
|
; CHECK-NEXT: store i32 1234, ptr [[BPTRM1]], align 1
|
||||||
; CHECK-NEXT: [[DPTR:%.*]] = bitcast i8* [[BPTRM1]] to i32*
|
; CHECK-NEXT: store i64 5678, ptr [[BPTR3]], align 1
|
||||||
; CHECK-NEXT: [[QPTR:%.*]] = bitcast i8* [[BPTR3]] to i64*
|
|
||||||
; CHECK-NEXT: store i32 1234, i32* [[DPTR]], align 1
|
|
||||||
; CHECK-NEXT: store i64 5678, i64* [[QPTR]], align 1
|
|
||||||
; CHECK-NEXT: ret i8 0
|
; CHECK-NEXT: ret i8 0
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
; Also check that alias.scope metadata doesn't get dropped
|
; Also check that alias.scope metadata doesn't get dropped
|
||||||
store i64 0, i64* %ptr, !alias.scope !32
|
store i64 0, ptr %ptr, !alias.scope !32
|
||||||
|
|
||||||
%bptr = bitcast i64* %ptr to i8*
|
%bptrm1 = getelementptr inbounds i8, ptr %ptr, i64 -1
|
||||||
%bptrm1 = getelementptr inbounds i8, i8* %bptr, i64 -1
|
%bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
||||||
%bptr3 = getelementptr inbounds i8, i8* %bptr, i64 3
|
|
||||||
%dptr = bitcast i8* %bptrm1 to i32*
|
|
||||||
%qptr = bitcast i8* %bptr3 to i64*
|
|
||||||
|
|
||||||
store i32 1234, i32* %dptr, align 1
|
store i32 1234, ptr %bptrm1, align 1
|
||||||
store i64 5678, i64* %qptr, align 1
|
store i64 5678, ptr %bptr3, align 1
|
||||||
|
|
||||||
ret i8 0
|
ret i8 0
|
||||||
}
|
}
|
||||||
|
@ -155,50 +138,44 @@ entry:
|
||||||
;; Test case from PR31777
|
;; Test case from PR31777
|
||||||
%union.U = type { i64 }
|
%union.U = type { i64 }
|
||||||
|
|
||||||
define void @foo(%union.U* nocapture %u) {
|
define void @foo(ptr nocapture %u) {
|
||||||
; CHECK-LABEL: @foo(
|
; CHECK-LABEL: @foo(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[I:%.*]] = getelementptr inbounds [[UNION_U:%.*]], %union.U* [[U:%.*]], i64 0, i32 0
|
; CHECK-NEXT: store i64 42, ptr [[U:%.*]], align 8
|
||||||
; CHECK-NEXT: store i64 42, i64* [[I]], align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%i = getelementptr inbounds %union.U, %union.U* %u, i64 0, i32 0
|
store i64 0, ptr %u, align 8, !dbg !22, !tbaa !26, !noalias !32, !nontemporal !29
|
||||||
store i64 0, i64* %i, align 8, !dbg !22, !tbaa !26, !noalias !32, !nontemporal !29
|
store i16 42, ptr %u, align 8
|
||||||
%s = bitcast %union.U* %u to i16*
|
|
||||||
store i16 42, i16* %s, align 8
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Don't crash by operating on stale data if we merge (kill) the last 2 stores.
|
; Don't crash by operating on stale data if we merge (kill) the last 2 stores.
|
||||||
|
|
||||||
define void @PR34074(i32* %x, i64* %y) {
|
define void @PR34074(ptr %x, ptr %y) {
|
||||||
; CHECK-LABEL: @PR34074(
|
; CHECK-LABEL: @PR34074(
|
||||||
; CHECK-NEXT: store i64 42, i64* %y
|
; CHECK-NEXT: store i64 42, ptr %y
|
||||||
; CHECK-NEXT: store i32 4, i32* %x
|
; CHECK-NEXT: store i32 4, ptr %x
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i64 42, i64* %y ; independent store
|
store i64 42, ptr %y ; independent store
|
||||||
%xbc = bitcast i32* %x to i8*
|
store i32 0, ptr %x ; big store of constant
|
||||||
store i32 0, i32* %x ; big store of constant
|
store i8 4, ptr %x ; small store with mergeable constant
|
||||||
store i8 4, i8* %xbc ; small store with mergeable constant
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; We can't eliminate the last store because P and Q may alias.
|
; We can't eliminate the last store because P and Q may alias.
|
||||||
|
|
||||||
define void @PR36129(i32* %P, i32* %Q) {
|
define void @PR36129(ptr %P, ptr %Q) {
|
||||||
; CHECK-LABEL: @PR36129(
|
; CHECK-LABEL: @PR36129(
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: [[P2:%.*]] = bitcast i32* [[P]] to i8*
|
; CHECK-NEXT: store i32 2, ptr [[Q:%.*]], align 4
|
||||||
; CHECK-NEXT: store i32 2, i32* [[Q:%.*]], align 4
|
; CHECK-NEXT: store i8 3, ptr [[P]], align 1
|
||||||
; CHECK-NEXT: store i8 3, i8* [[P2]], align 1
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 1, i32* %P, align 4
|
store i32 1, ptr %P, align 4
|
||||||
%P2 = bitcast i32* %P to i8*
|
store i32 2, ptr %Q, align 4
|
||||||
store i32 2, i32* %Q, align 4
|
store i8 3, ptr %P, align 1
|
||||||
store i8 3, i8* %P2, align 1
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,214 +3,212 @@
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||||
|
|
||||||
declare noalias i8* @malloc(i64)
|
declare noalias ptr @malloc(i64)
|
||||||
|
|
||||||
declare void @foo()
|
declare void @foo()
|
||||||
declare void @capture(i8*)
|
declare void @capture(ptr)
|
||||||
|
|
||||||
; Check that we do not remove the second store, as %m is returned.
|
; Check that we do not remove the second store, as %m is returned.
|
||||||
define i8* @test_return_captures_1() {
|
define ptr @test_return_captures_1() {
|
||||||
; CHECK-LABEL: @test_return_captures_1(
|
; CHECK-LABEL: @test_return_captures_1(
|
||||||
; CHECK-NEXT: [[M:%.*]] = call i8* @malloc(i64 24)
|
; CHECK-NEXT: [[M:%.*]] = call ptr @malloc(i64 24)
|
||||||
; CHECK-NEXT: store i8 1, i8* [[M]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: ret i8* [[M]]
|
; CHECK-NEXT: ret ptr [[M]]
|
||||||
;
|
;
|
||||||
%m = call i8* @malloc(i64 24)
|
%m = call ptr @malloc(i64 24)
|
||||||
store i8 0, i8* %m
|
store i8 0, ptr %m
|
||||||
store i8 1, i8* %m
|
store i8 1, ptr %m
|
||||||
ret i8* %m
|
ret ptr %m
|
||||||
}
|
}
|
||||||
|
|
||||||
; Same as @test_return_captures_1, but across BBs.
|
; Same as @test_return_captures_1, but across BBs.
|
||||||
define i8* @test_return_captures_2() {
|
define ptr @test_return_captures_2() {
|
||||||
; CHECK-LABEL: @test_return_captures_2(
|
; CHECK-LABEL: @test_return_captures_2(
|
||||||
; CHECK-NEXT: [[M:%.*]] = call i8* @malloc(i64 24)
|
; CHECK-NEXT: [[M:%.*]] = call ptr @malloc(i64 24)
|
||||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: store i8 1, i8* [[M]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: ret i8* [[M]]
|
; CHECK-NEXT: ret ptr [[M]]
|
||||||
;
|
;
|
||||||
%m = call i8* @malloc(i64 24)
|
%m = call ptr @malloc(i64 24)
|
||||||
store i8 0, i8* %m
|
store i8 0, ptr %m
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
store i8 1, i8* %m
|
store i8 1, ptr %m
|
||||||
ret i8* %m
|
ret ptr %m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
%S1 = type { i8 * }
|
%S1 = type { ptr }
|
||||||
|
|
||||||
; We cannot remove the last store to %m, because it escapes by storing it to %E.
|
; We cannot remove the last store to %m, because it escapes by storing it to %E.
|
||||||
define void @test_malloc_capture_1(%S1* %E) {
|
define void @test_malloc_capture_1(ptr %E) {
|
||||||
; CHECK-LABEL: @test_malloc_capture_1(
|
; CHECK-LABEL: @test_malloc_capture_1(
|
||||||
; CHECK-NEXT: [[M:%.*]] = call i8* @malloc(i64 24)
|
; CHECK-NEXT: [[M:%.*]] = call ptr @malloc(i64 24)
|
||||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: [[F_PTR:%.*]] = getelementptr [[S1:%.*]], %S1* [[E:%.*]], i32 0, i32 0
|
; CHECK-NEXT: store ptr [[M]], ptr [[E:%.*]], align 4
|
||||||
; CHECK-NEXT: store i8* [[M]], i8** [[F_PTR]], align 4
|
; CHECK-NEXT: store i8 1, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: store i8 1, i8* [[M]], align 1
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%m = call i8* @malloc(i64 24)
|
%m = call ptr @malloc(i64 24)
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
%f.ptr = getelementptr %S1, %S1* %E, i32 0, i32 0
|
store ptr %m, ptr %E
|
||||||
store i8* %m, i8** %f.ptr
|
store i8 1, ptr %m
|
||||||
store i8 1, i8* %m
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Check we do not eliminate either store. The first one cannot be eliminated,
|
; Check we do not eliminate either store. The first one cannot be eliminated,
|
||||||
; due to the call of @capture. The second one because %m escapes.
|
; due to the call of @capture. The second one because %m escapes.
|
||||||
define i8* @test_malloc_capture_2() {
|
define ptr @test_malloc_capture_2() {
|
||||||
; CHECK-LABEL: @test_malloc_capture_2(
|
; CHECK-LABEL: @test_malloc_capture_2(
|
||||||
; CHECK-NEXT: [[M:%.*]] = call i8* @malloc(i64 24)
|
; CHECK-NEXT: [[M:%.*]] = call ptr @malloc(i64 24)
|
||||||
; CHECK-NEXT: store i8 0, i8* [[M]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: call void @capture(i8* [[M]])
|
; CHECK-NEXT: call void @capture(ptr [[M]])
|
||||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: store i8 1, i8* [[M]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: ret i8* [[M]]
|
; CHECK-NEXT: ret ptr [[M]]
|
||||||
;
|
;
|
||||||
%m = call i8* @malloc(i64 24)
|
%m = call ptr @malloc(i64 24)
|
||||||
store i8 0, i8* %m
|
store i8 0, ptr %m
|
||||||
call void @capture(i8* %m)
|
call void @capture(ptr %m)
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
store i8 1, i8* %m
|
store i8 1, ptr %m
|
||||||
ret i8* %m
|
ret ptr %m
|
||||||
}
|
}
|
||||||
|
|
||||||
; We can remove the first store store i8 0, i8* %m because there are no throwing
|
; We can remove the first store store i8 0, ptr %m because there are no throwing
|
||||||
; instructions between the 2 stores and also %m escapes after the killing store.
|
; instructions between the 2 stores and also %m escapes after the killing store.
|
||||||
define i8* @test_malloc_capture_3() {
|
define ptr @test_malloc_capture_3() {
|
||||||
; CHECK-LABEL: @test_malloc_capture_3(
|
; CHECK-LABEL: @test_malloc_capture_3(
|
||||||
; CHECK-NEXT: [[M:%.*]] = call i8* @malloc(i64 24)
|
; CHECK-NEXT: [[M:%.*]] = call ptr @malloc(i64 24)
|
||||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: store i8 1, i8* [[M]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: call void @capture(i8* [[M]])
|
; CHECK-NEXT: call void @capture(ptr [[M]])
|
||||||
; CHECK-NEXT: ret i8* [[M]]
|
; CHECK-NEXT: ret ptr [[M]]
|
||||||
;
|
;
|
||||||
%m = call i8* @malloc(i64 24)
|
%m = call ptr @malloc(i64 24)
|
||||||
store i8 0, i8* %m
|
store i8 0, ptr %m
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
store i8 1, i8* %m
|
store i8 1, ptr %m
|
||||||
call void @capture(i8* %m)
|
call void @capture(ptr %m)
|
||||||
ret i8* %m
|
ret ptr %m
|
||||||
}
|
}
|
||||||
|
|
||||||
; TODO: We could remove the first store store i8 0, i8* %m because %m escapes
|
; TODO: We could remove the first store store i8 0, ptr %m because %m escapes
|
||||||
; after the killing store.
|
; after the killing store.
|
||||||
define i8* @test_malloc_capture_4() {
|
define ptr @test_malloc_capture_4() {
|
||||||
; CHECK-LABEL: @test_malloc_capture_4(
|
; CHECK-LABEL: @test_malloc_capture_4(
|
||||||
; CHECK-NEXT: [[M:%.*]] = call i8* @malloc(i64 24)
|
; CHECK-NEXT: [[M:%.*]] = call ptr @malloc(i64 24)
|
||||||
; CHECK-NEXT: store i8 0, i8* [[M]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: call void @may_throw_readnone()
|
; CHECK-NEXT: call void @may_throw_readnone()
|
||||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: store i8 1, i8* [[M]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: call void @capture(i8* [[M]])
|
; CHECK-NEXT: call void @capture(ptr [[M]])
|
||||||
; CHECK-NEXT: ret i8* [[M]]
|
; CHECK-NEXT: ret ptr [[M]]
|
||||||
;
|
;
|
||||||
|
|
||||||
%m = call i8* @malloc(i64 24)
|
%m = call ptr @malloc(i64 24)
|
||||||
store i8 0, i8* %m
|
store i8 0, ptr %m
|
||||||
call void @may_throw_readnone()
|
call void @may_throw_readnone()
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
store i8 1, i8* %m
|
store i8 1, ptr %m
|
||||||
call void @capture(i8* %m)
|
call void @capture(ptr %m)
|
||||||
ret i8* %m
|
ret ptr %m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
; We cannot remove the first store store i8 0, i8* %m because %m escapes
|
; We cannot remove the first store store i8 0, ptr %m because %m escapes
|
||||||
; before the killing store and we may throw in between.
|
; before the killing store and we may throw in between.
|
||||||
define i8* @test_malloc_capture_5() {
|
define ptr @test_malloc_capture_5() {
|
||||||
; CHECK-LABEL: @test_malloc_capture_5(
|
; CHECK-LABEL: @test_malloc_capture_5(
|
||||||
; CHECK-NEXT: [[M:%.*]] = call i8* @malloc(i64 24)
|
; CHECK-NEXT: [[M:%.*]] = call ptr @malloc(i64 24)
|
||||||
; CHECK-NEXT: call void @capture(i8* [[M]])
|
; CHECK-NEXT: call void @capture(ptr [[M]])
|
||||||
; CHECK-NEXT: store i8 0, i8* [[M]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: call void @may_throw_readnone()
|
; CHECK-NEXT: call void @may_throw_readnone()
|
||||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: store i8 1, i8* [[M]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: ret i8* [[M]]
|
; CHECK-NEXT: ret ptr [[M]]
|
||||||
;
|
;
|
||||||
|
|
||||||
%m = call i8* @malloc(i64 24)
|
%m = call ptr @malloc(i64 24)
|
||||||
call void @capture(i8* %m)
|
call void @capture(ptr %m)
|
||||||
store i8 0, i8* %m
|
store i8 0, ptr %m
|
||||||
call void @may_throw_readnone()
|
call void @may_throw_readnone()
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
store i8 1, i8* %m
|
store i8 1, ptr %m
|
||||||
ret i8* %m
|
ret ptr %m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
; TODO: We could remove the first store 'store i8 0, i8* %m' even though there
|
; TODO: We could remove the first store 'store i8 0, ptr %m' even though there
|
||||||
; is a throwing instruction between them, because %m escapes after the killing
|
; is a throwing instruction between them, because %m escapes after the killing
|
||||||
; store.
|
; store.
|
||||||
define i8* @test_malloc_capture_6() {
|
define ptr @test_malloc_capture_6() {
|
||||||
; CHECK-LABEL: @test_malloc_capture_6(
|
; CHECK-LABEL: @test_malloc_capture_6(
|
||||||
; CHECK-NEXT: [[M:%.*]] = call i8* @malloc(i64 24)
|
; CHECK-NEXT: [[M:%.*]] = call ptr @malloc(i64 24)
|
||||||
; CHECK-NEXT: store i8 0, i8* [[M]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: call void @may_throw_readnone()
|
; CHECK-NEXT: call void @may_throw_readnone()
|
||||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: store i8 1, i8* [[M]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: call void @capture(i8* [[M]])
|
; CHECK-NEXT: call void @capture(ptr [[M]])
|
||||||
; CHECK-NEXT: ret i8* [[M]]
|
; CHECK-NEXT: ret ptr [[M]]
|
||||||
;
|
;
|
||||||
|
|
||||||
%m = call i8* @malloc(i64 24)
|
%m = call ptr @malloc(i64 24)
|
||||||
store i8 0, i8* %m
|
store i8 0, ptr %m
|
||||||
call void @may_throw_readnone()
|
call void @may_throw_readnone()
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
store i8 1, i8* %m
|
store i8 1, ptr %m
|
||||||
call void @capture(i8* %m)
|
call void @capture(ptr %m)
|
||||||
ret i8* %m
|
ret ptr %m
|
||||||
}
|
}
|
||||||
|
|
||||||
; We *could* remove the first store 'store i8 0, i8* %m' even though there is a
|
; We *could* remove the first store 'store i8 0, ptr %m' even though there is a
|
||||||
; throwing instruction between them, because %m escapes after the killing store.
|
; throwing instruction between them, because %m escapes after the killing store.
|
||||||
; But this would require using PointerMayBeCapturedBefore in
|
; But this would require using PointerMayBeCapturedBefore in
|
||||||
; isInvisibleToCallerBeforeRet, which we currently do not do to limit
|
; isInvisibleToCallerBeforeRet, which we currently do not do to limit
|
||||||
; compile-time, as this appears to hardly ever lead to more stores eliminated
|
; compile-time, as this appears to hardly ever lead to more stores eliminated
|
||||||
; in practice.
|
; in practice.
|
||||||
define i8* @test_malloc_capture_7() {
|
define ptr @test_malloc_capture_7() {
|
||||||
; CHECK-LABEL: @test_malloc_capture_7(
|
; CHECK-LABEL: @test_malloc_capture_7(
|
||||||
; CHECK-NEXT: [[M:%.*]] = call i8* @malloc(i64 24)
|
; CHECK-NEXT: [[M:%.*]] = call ptr @malloc(i64 24)
|
||||||
; CHECK-NEXT: store i8 0, i8* [[M]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: call void @may_throw()
|
; CHECK-NEXT: call void @may_throw()
|
||||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: store i8 1, i8* [[M]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: call void @capture(i8* [[M]])
|
; CHECK-NEXT: call void @capture(ptr [[M]])
|
||||||
; CHECK-NEXT: ret i8* [[M]]
|
; CHECK-NEXT: ret ptr [[M]]
|
||||||
;
|
;
|
||||||
|
|
||||||
%m = call i8* @malloc(i64 24)
|
%m = call ptr @malloc(i64 24)
|
||||||
store i8 0, i8* %m
|
store i8 0, ptr %m
|
||||||
call void @may_throw()
|
call void @may_throw()
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
store i8 1, i8* %m
|
store i8 1, ptr %m
|
||||||
call void @capture(i8* %m)
|
call void @capture(ptr %m)
|
||||||
ret i8* %m
|
ret ptr %m
|
||||||
}
|
}
|
||||||
|
|
||||||
; Stores to stack objects can be eliminated if they are not captured inside the function.
|
; Stores to stack objects can be eliminated if they are not captured inside the function.
|
||||||
|
@ -222,100 +220,98 @@ define void @test_alloca_nocapture_1() {
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%m = alloca i8
|
%m = alloca i8
|
||||||
store i8 0, i8* %m
|
store i8 0, ptr %m
|
||||||
call void @foo()
|
call void @foo()
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
store i8 1, i8* %m
|
store i8 1, ptr %m
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Cannot remove first store i8 0, i8* %m, as the call to @capture captures the object.
|
; Cannot remove first store i8 0, ptr %m, as the call to @capture captures the object.
|
||||||
define void @test_alloca_capture_1() {
|
define void @test_alloca_capture_1() {
|
||||||
; CHECK-LABEL: @test_alloca_capture_1(
|
; CHECK-LABEL: @test_alloca_capture_1(
|
||||||
; CHECK-NEXT: [[M:%.*]] = alloca i8, align 1
|
; CHECK-NEXT: [[M:%.*]] = alloca i8, align 1
|
||||||
; CHECK-NEXT: store i8 0, i8* [[M]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: call void @capture(i8* [[M]])
|
; CHECK-NEXT: call void @capture(ptr [[M]])
|
||||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%m = alloca i8
|
%m = alloca i8
|
||||||
store i8 0, i8* %m
|
store i8 0, ptr %m
|
||||||
call void @capture(i8* %m)
|
call void @capture(ptr %m)
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
store i8 1, i8* %m
|
store i8 1, ptr %m
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; We can remove the last store to %m, even though it escapes because the alloca
|
; We can remove the last store to %m, even though it escapes because the alloca
|
||||||
; becomes invalid after the function returns.
|
; becomes invalid after the function returns.
|
||||||
define void @test_alloca_capture_2(%S1* %E) {
|
define void @test_alloca_capture_2(ptr %E) {
|
||||||
; CHECK-LABEL: @test_alloca_capture_2(
|
; CHECK-LABEL: @test_alloca_capture_2(
|
||||||
; CHECK-NEXT: [[M:%.*]] = alloca i8, align 1
|
; CHECK-NEXT: [[M:%.*]] = alloca i8, align 1
|
||||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: [[F_PTR:%.*]] = getelementptr [[S1:%.*]], %S1* [[E:%.*]], i32 0, i32 0
|
; CHECK-NEXT: store ptr [[M]], ptr [[E:%.*]], align 4
|
||||||
; CHECK-NEXT: store i8* [[M]], i8** [[F_PTR]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%m = alloca i8
|
%m = alloca i8
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
%f.ptr = getelementptr %S1, %S1* %E, i32 0, i32 0
|
store ptr %m, ptr %E
|
||||||
store i8* %m, i8** %f.ptr
|
store i8 1, ptr %m
|
||||||
store i8 1, i8* %m
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Readnone functions are not modeled in MemorySSA, but could throw.
|
; Readnone functions are not modeled in MemorySSA, but could throw.
|
||||||
; Make sure we do not eliminate the first store 'store i8 2, i8* %call'
|
; Make sure we do not eliminate the first store 'store i8 2, ptr %call'
|
||||||
define void @malloc_capture_throw_1() {
|
define void @malloc_capture_throw_1() {
|
||||||
; CHECK-LABEL: @malloc_capture_throw_1(
|
; CHECK-LABEL: @malloc_capture_throw_1(
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = call i8* @malloc(i64 1)
|
; CHECK-NEXT: [[CALL:%.*]] = call ptr @malloc(i64 1)
|
||||||
; CHECK-NEXT: call void @may_capture(i8* [[CALL]])
|
; CHECK-NEXT: call void @may_capture(ptr [[CALL]])
|
||||||
; CHECK-NEXT: store i8 2, i8* [[CALL]], align 1
|
; CHECK-NEXT: store i8 2, ptr [[CALL]], align 1
|
||||||
; CHECK-NEXT: call void @may_throw_readnone()
|
; CHECK-NEXT: call void @may_throw_readnone()
|
||||||
; CHECK-NEXT: store i8 3, i8* [[CALL]], align 1
|
; CHECK-NEXT: store i8 3, ptr [[CALL]], align 1
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%call = call i8* @malloc(i64 1)
|
%call = call ptr @malloc(i64 1)
|
||||||
call void @may_capture(i8* %call)
|
call void @may_capture(ptr %call)
|
||||||
store i8 2, i8* %call, align 1
|
store i8 2, ptr %call, align 1
|
||||||
call void @may_throw_readnone()
|
call void @may_throw_readnone()
|
||||||
store i8 3, i8* %call, align 1
|
store i8 3, ptr %call, align 1
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Readnone functions are not modeled in MemorySSA, but could throw.
|
; Readnone functions are not modeled in MemorySSA, but could throw.
|
||||||
; Make sure we do not eliminate the first store 'store i8 2, i8* %call'
|
; Make sure we do not eliminate the first store 'store i8 2, ptr %call'
|
||||||
define void @malloc_capture_throw_2() {
|
define void @malloc_capture_throw_2() {
|
||||||
; CHECK-LABEL: @malloc_capture_throw_2(
|
; CHECK-LABEL: @malloc_capture_throw_2(
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = call i8* @malloc(i64 1)
|
; CHECK-NEXT: [[CALL:%.*]] = call ptr @malloc(i64 1)
|
||||||
; CHECK-NEXT: call void @may_capture(i8* [[CALL]])
|
; CHECK-NEXT: call void @may_capture(ptr [[CALL]])
|
||||||
; CHECK-NEXT: store i8 2, i8* [[CALL]], align 1
|
; CHECK-NEXT: store i8 2, ptr [[CALL]], align 1
|
||||||
; CHECK-NEXT: br label [[BB:%.*]]
|
; CHECK-NEXT: br label [[BB:%.*]]
|
||||||
; CHECK: bb:
|
; CHECK: bb:
|
||||||
; CHECK-NEXT: call void @may_throw_readnone()
|
; CHECK-NEXT: call void @may_throw_readnone()
|
||||||
; CHECK-NEXT: store i8 3, i8* [[CALL]], align 1
|
; CHECK-NEXT: store i8 3, ptr [[CALL]], align 1
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%call = call i8* @malloc(i64 1)
|
%call = call ptr @malloc(i64 1)
|
||||||
call void @may_capture(i8* %call)
|
call void @may_capture(ptr %call)
|
||||||
store i8 2, i8* %call, align 1
|
store i8 2, ptr %call, align 1
|
||||||
br label %bb
|
br label %bb
|
||||||
|
|
||||||
bb:
|
bb:
|
||||||
call void @may_throw_readnone()
|
call void @may_throw_readnone()
|
||||||
store i8 3, i8* %call, align 1
|
store i8 3, ptr %call, align 1
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
declare void @may_capture(i8*)
|
declare void @may_capture(ptr)
|
||||||
declare void @may_throw_readnone() readnone
|
declare void @may_throw_readnone() readnone
|
||||||
declare void @may_throw()
|
declare void @may_throw()
|
||||||
|
|
|
@ -6,15 +6,15 @@ declare void @f()
|
||||||
declare i32 @__CxxFrameHandler3(...)
|
declare i32 @__CxxFrameHandler3(...)
|
||||||
|
|
||||||
|
|
||||||
; Make sure we do not eliminate `store i32 20, i32* %sv`. Even though it is a store
|
; Make sure we do not eliminate `store i32 20, ptr %sv`. Even though it is a store
|
||||||
; to a stack object, we can read it in the landing/catchpad.
|
; to a stack object, we can read it in the landing/catchpad.
|
||||||
define void @test12(i32* %p) personality i32 (...)* @__CxxFrameHandler3 {
|
define void @test12(ptr %p) personality ptr @__CxxFrameHandler3 {
|
||||||
; CHECK-LABEL: @test12(
|
; CHECK-LABEL: @test12(
|
||||||
; CHECK-NEXT: block1:
|
; CHECK-NEXT: block1:
|
||||||
; CHECK-NEXT: [[SV:%.*]] = alloca i32
|
; CHECK-NEXT: [[SV:%.*]] = alloca i32
|
||||||
; CHECK-NEXT: br label [[BLOCK2:%.*]]
|
; CHECK-NEXT: br label [[BLOCK2:%.*]]
|
||||||
; CHECK: block2:
|
; CHECK: block2:
|
||||||
; CHECK-NEXT: store i32 20, i32* [[SV]]
|
; CHECK-NEXT: store i32 20, ptr [[SV]]
|
||||||
; CHECK-NEXT: invoke void @f()
|
; CHECK-NEXT: invoke void @f()
|
||||||
; CHECK-NEXT: to label [[BLOCK3:%.*]] unwind label [[CATCH_DISPATCH:%.*]]
|
; CHECK-NEXT: to label [[BLOCK3:%.*]] unwind label [[CATCH_DISPATCH:%.*]]
|
||||||
; CHECK: block3:
|
; CHECK: block3:
|
||||||
|
@ -23,7 +23,7 @@ define void @test12(i32* %p) personality i32 (...)* @__CxxFrameHandler3 {
|
||||||
; CHECK-NEXT: [[CS1:%.*]] = catchswitch within none [label %catch] unwind label [[CLEANUP:%.*]]
|
; CHECK-NEXT: [[CS1:%.*]] = catchswitch within none [label %catch] unwind label [[CLEANUP:%.*]]
|
||||||
; CHECK: catch:
|
; CHECK: catch:
|
||||||
; CHECK-NEXT: [[C:%.*]] = catchpad within [[CS1]] []
|
; CHECK-NEXT: [[C:%.*]] = catchpad within [[CS1]] []
|
||||||
; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[SV]]
|
; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[SV]]
|
||||||
; CHECK-NEXT: br label [[EXIT]]
|
; CHECK-NEXT: br label [[EXIT]]
|
||||||
; CHECK: cleanup:
|
; CHECK: cleanup:
|
||||||
; CHECK-NEXT: [[C1:%.*]] = cleanuppad within none []
|
; CHECK-NEXT: [[C1:%.*]] = cleanuppad within none []
|
||||||
|
@ -36,12 +36,12 @@ block1:
|
||||||
br label %block2
|
br label %block2
|
||||||
|
|
||||||
block2:
|
block2:
|
||||||
store i32 20, i32* %sv
|
store i32 20, ptr %sv
|
||||||
invoke void @f()
|
invoke void @f()
|
||||||
to label %block3 unwind label %catch.dispatch
|
to label %block3 unwind label %catch.dispatch
|
||||||
|
|
||||||
block3:
|
block3:
|
||||||
store i32 30, i32* %sv
|
store i32 30, ptr %sv
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
catch.dispatch:
|
catch.dispatch:
|
||||||
|
@ -49,7 +49,7 @@ catch.dispatch:
|
||||||
|
|
||||||
catch:
|
catch:
|
||||||
%c = catchpad within %cs1 []
|
%c = catchpad within %cs1 []
|
||||||
%lv = load i32, i32* %sv
|
%lv = load i32, ptr %sv
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
@ -57,6 +57,6 @@ cleanup:
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
store i32 40, i32* %sv
|
store i32 40, ptr %sv
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,8 @@ define void @test.1() {
|
||||||
; CHECK-NEXT: br label [[LOOP_1:%.*]]
|
; CHECK-NEXT: br label [[LOOP_1:%.*]]
|
||||||
; CHECK: loop.1:
|
; CHECK: loop.1:
|
||||||
; CHECK-NEXT: [[IV_1:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_1_NEXT:%.*]], [[LOOP_1]] ]
|
; CHECK-NEXT: [[IV_1:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_1_NEXT:%.*]], [[LOOP_1]] ]
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [100 x i32], [100 x i32]* [[A]], i64 0, i64 [[IV_1]]
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [100 x i32], ptr [[A]], i64 0, i64 [[IV_1]]
|
||||||
; CHECK-NEXT: store i32 0, i32* [[ARRAYIDX1]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[ARRAYIDX1]], align 4
|
||||||
; CHECK-NEXT: [[IV_1_NEXT]] = add nsw i64 [[IV_1]], 1
|
; CHECK-NEXT: [[IV_1_NEXT]] = add nsw i64 [[IV_1]], 1
|
||||||
; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV_1_NEXT]], 100
|
; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV_1_NEXT]], 100
|
||||||
; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_1]], label [[LOOP_2_PH:%.*]]
|
; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_1]], label [[LOOP_2_PH:%.*]]
|
||||||
|
@ -25,13 +25,13 @@ define void @test.1() {
|
||||||
; CHECK-NEXT: br label [[LOOP_2:%.*]]
|
; CHECK-NEXT: br label [[LOOP_2:%.*]]
|
||||||
; CHECK: loop.2:
|
; CHECK: loop.2:
|
||||||
; CHECK-NEXT: [[IV_2:%.*]] = phi i64 [ [[IV_2_NEXT:%.*]], [[LOOP_2]] ], [ 0, [[LOOP_2_PH]] ]
|
; CHECK-NEXT: [[IV_2:%.*]] = phi i64 [ [[IV_2_NEXT:%.*]], [[LOOP_2]] ], [ 0, [[LOOP_2_PH]] ]
|
||||||
; CHECK-NEXT: [[PTR_IV_2:%.*]] = getelementptr inbounds [100 x i32], [100 x i32]* [[A]], i64 0, i64 [[IV_2]]
|
; CHECK-NEXT: [[PTR_IV_2:%.*]] = getelementptr inbounds [100 x i32], ptr [[A]], i64 0, i64 [[IV_2]]
|
||||||
; CHECK-NEXT: [[L_0:%.*]] = load i32, i32* [[PTR_IV_2]], align 4
|
; CHECK-NEXT: [[L_0:%.*]] = load i32, ptr [[PTR_IV_2]], align 4
|
||||||
; CHECK-NEXT: call void @use(i32 [[L_0]])
|
; CHECK-NEXT: call void @use(i32 [[L_0]])
|
||||||
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[IV_2]], 1
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[IV_2]], 1
|
||||||
; CHECK-NEXT: [[PTR_IV_2_ADD_1:%.*]] = getelementptr inbounds [100 x i32], [100 x i32]* [[A]], i64 0, i64 [[ADD]]
|
; CHECK-NEXT: [[PTR_IV_2_ADD_1:%.*]] = getelementptr inbounds [100 x i32], ptr [[A]], i64 0, i64 [[ADD]]
|
||||||
; CHECK-NEXT: store i32 10, i32* [[PTR_IV_2_ADD_1]], align 4
|
; CHECK-NEXT: store i32 10, ptr [[PTR_IV_2_ADD_1]], align 4
|
||||||
; CHECK-NEXT: [[L_1:%.*]] = load i32, i32* [[PTR_IV_2]], align 4
|
; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV_2]], align 4
|
||||||
; CHECK-NEXT: call void @use(i32 [[L_1]])
|
; CHECK-NEXT: call void @use(i32 [[L_1]])
|
||||||
; CHECK-NEXT: [[IV_2_NEXT]] = add nsw i64 [[IV_2]], 1
|
; CHECK-NEXT: [[IV_2_NEXT]] = add nsw i64 [[IV_2]], 1
|
||||||
; CHECK-NEXT: [[C_2:%.*]] = icmp slt i64 [[IV_2_NEXT]], 100
|
; CHECK-NEXT: [[C_2:%.*]] = icmp slt i64 [[IV_2_NEXT]], 100
|
||||||
|
@ -45,8 +45,8 @@ entry:
|
||||||
|
|
||||||
loop.1:
|
loop.1:
|
||||||
%iv.1 = phi i64 [ 1, %entry ], [ %iv.1.next, %loop.1 ]
|
%iv.1 = phi i64 [ 1, %entry ], [ %iv.1.next, %loop.1 ]
|
||||||
%arrayidx1 = getelementptr inbounds [100 x i32], [100 x i32]* %A, i64 0, i64 %iv.1
|
%arrayidx1 = getelementptr inbounds [100 x i32], ptr %A, i64 0, i64 %iv.1
|
||||||
store i32 0, i32* %arrayidx1, align 4
|
store i32 0, ptr %arrayidx1, align 4
|
||||||
%iv.1.next = add nsw i64 %iv.1, 1
|
%iv.1.next = add nsw i64 %iv.1, 1
|
||||||
%c.1 = icmp slt i64 %iv.1.next, 100
|
%c.1 = icmp slt i64 %iv.1.next, 100
|
||||||
br i1 %c.1, label %loop.1, label %loop.2.ph
|
br i1 %c.1, label %loop.1, label %loop.2.ph
|
||||||
|
@ -56,13 +56,13 @@ loop.2.ph:
|
||||||
|
|
||||||
loop.2:
|
loop.2:
|
||||||
%iv.2 = phi i64 [ %iv.2.next, %loop.2 ], [ 0, %loop.2.ph ]
|
%iv.2 = phi i64 [ %iv.2.next, %loop.2 ], [ 0, %loop.2.ph ]
|
||||||
%ptr.iv.2 = getelementptr inbounds [100 x i32], [100 x i32]* %A, i64 0, i64 %iv.2
|
%ptr.iv.2 = getelementptr inbounds [100 x i32], ptr %A, i64 0, i64 %iv.2
|
||||||
%l.0 = load i32, i32* %ptr.iv.2, align 4
|
%l.0 = load i32, ptr %ptr.iv.2, align 4
|
||||||
call void @use(i32 %l.0)
|
call void @use(i32 %l.0)
|
||||||
%add = add nsw i64 %iv.2, 1
|
%add = add nsw i64 %iv.2, 1
|
||||||
%ptr.iv.2.add.1 = getelementptr inbounds [100 x i32], [100 x i32]* %A, i64 0, i64 %add
|
%ptr.iv.2.add.1 = getelementptr inbounds [100 x i32], ptr %A, i64 0, i64 %add
|
||||||
store i32 10, i32* %ptr.iv.2.add.1, align 4
|
store i32 10, ptr %ptr.iv.2.add.1, align 4
|
||||||
%l.1 = load i32, i32* %ptr.iv.2, align 4
|
%l.1 = load i32, ptr %ptr.iv.2, align 4
|
||||||
call void @use(i32 %l.1)
|
call void @use(i32 %l.1)
|
||||||
%iv.2.next = add nsw i64 %iv.2, 1
|
%iv.2.next = add nsw i64 %iv.2, 1
|
||||||
%c.2 = icmp slt i64 %iv.2.next, 100
|
%c.2 = icmp slt i64 %iv.2.next, 100
|
||||||
|
@ -79,12 +79,11 @@ define void @test.2() {
|
||||||
; CHECK-LABEL: @test.2(
|
; CHECK-LABEL: @test.2(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca [100 x i32], align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca [100 x i32], align 4
|
||||||
; CHECK-NEXT: [[A_CAST:%.*]] = bitcast [100 x i32]* [[A]] to i8*
|
|
||||||
; CHECK-NEXT: br label [[LOOP_1:%.*]]
|
; CHECK-NEXT: br label [[LOOP_1:%.*]]
|
||||||
; CHECK: loop.1:
|
; CHECK: loop.1:
|
||||||
; CHECK-NEXT: [[IV_1:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_1_NEXT:%.*]], [[LOOP_1]] ]
|
; CHECK-NEXT: [[IV_1:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_1_NEXT:%.*]], [[LOOP_1]] ]
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [100 x i32], [100 x i32]* [[A]], i64 0, i64 [[IV_1]]
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [100 x i32], ptr [[A]], i64 0, i64 [[IV_1]]
|
||||||
; CHECK-NEXT: store i32 0, i32* [[ARRAYIDX1]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[ARRAYIDX1]], align 4
|
||||||
; CHECK-NEXT: [[IV_1_NEXT]] = add nsw i64 [[IV_1]], 1
|
; CHECK-NEXT: [[IV_1_NEXT]] = add nsw i64 [[IV_1]], 1
|
||||||
; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV_1_NEXT]], 100
|
; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV_1_NEXT]], 100
|
||||||
; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_1]], label [[LOOP_2_PH:%.*]]
|
; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_1]], label [[LOOP_2_PH:%.*]]
|
||||||
|
@ -92,30 +91,29 @@ define void @test.2() {
|
||||||
; CHECK-NEXT: br label [[LOOP_2:%.*]]
|
; CHECK-NEXT: br label [[LOOP_2:%.*]]
|
||||||
; CHECK: loop.2:
|
; CHECK: loop.2:
|
||||||
; CHECK-NEXT: [[IV_2:%.*]] = phi i64 [ [[IV_2_NEXT:%.*]], [[LOOP_2]] ], [ 0, [[LOOP_2_PH]] ]
|
; CHECK-NEXT: [[IV_2:%.*]] = phi i64 [ [[IV_2_NEXT:%.*]], [[LOOP_2]] ], [ 0, [[LOOP_2_PH]] ]
|
||||||
; CHECK-NEXT: [[PTR_IV_2:%.*]] = getelementptr inbounds [100 x i32], [100 x i32]* [[A]], i64 0, i64 [[IV_2]]
|
; CHECK-NEXT: [[PTR_IV_2:%.*]] = getelementptr inbounds [100 x i32], ptr [[A]], i64 0, i64 [[IV_2]]
|
||||||
; CHECK-NEXT: [[L_0:%.*]] = load i32, i32* [[PTR_IV_2]], align 4
|
; CHECK-NEXT: [[L_0:%.*]] = load i32, ptr [[PTR_IV_2]], align 4
|
||||||
; CHECK-NEXT: call void @use(i32 [[L_0]])
|
; CHECK-NEXT: call void @use(i32 [[L_0]])
|
||||||
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[IV_2]], 1
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[IV_2]], 1
|
||||||
; CHECK-NEXT: [[PTR_IV_2_ADD_1:%.*]] = getelementptr inbounds [100 x i32], [100 x i32]* [[A]], i64 0, i64 [[ADD]]
|
; CHECK-NEXT: [[PTR_IV_2_ADD_1:%.*]] = getelementptr inbounds [100 x i32], ptr [[A]], i64 0, i64 [[ADD]]
|
||||||
; CHECK-NEXT: store i32 10, i32* [[PTR_IV_2_ADD_1]], align 4
|
; CHECK-NEXT: store i32 10, ptr [[PTR_IV_2_ADD_1]], align 4
|
||||||
; CHECK-NEXT: [[L_1:%.*]] = load i32, i32* [[PTR_IV_2]], align 4
|
; CHECK-NEXT: [[L_1:%.*]] = load i32, ptr [[PTR_IV_2]], align 4
|
||||||
; CHECK-NEXT: call void @use(i32 [[L_1]])
|
; CHECK-NEXT: call void @use(i32 [[L_1]])
|
||||||
; CHECK-NEXT: [[IV_2_NEXT]] = add nsw i64 [[IV_2]], 1
|
; CHECK-NEXT: [[IV_2_NEXT]] = add nsw i64 [[IV_2]], 1
|
||||||
; CHECK-NEXT: [[C_2:%.*]] = icmp slt i64 [[IV_2_NEXT]], 100
|
; CHECK-NEXT: [[C_2:%.*]] = icmp slt i64 [[IV_2_NEXT]], 100
|
||||||
; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_2]], label [[EXIT:%.*]]
|
; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_2]], label [[EXIT:%.*]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 400, i8* nonnull [[A_CAST]])
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 400, ptr nonnull [[A]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%A = alloca [100 x i32], align 4
|
%A = alloca [100 x i32], align 4
|
||||||
%A.cast = bitcast [100 x i32]* %A to i8*
|
|
||||||
br label %loop.1
|
br label %loop.1
|
||||||
|
|
||||||
loop.1:
|
loop.1:
|
||||||
%iv.1 = phi i64 [ 1, %entry ], [ %iv.1.next, %loop.1 ]
|
%iv.1 = phi i64 [ 1, %entry ], [ %iv.1.next, %loop.1 ]
|
||||||
%arrayidx1 = getelementptr inbounds [100 x i32], [100 x i32]* %A, i64 0, i64 %iv.1
|
%arrayidx1 = getelementptr inbounds [100 x i32], ptr %A, i64 0, i64 %iv.1
|
||||||
store i32 0, i32* %arrayidx1, align 4
|
store i32 0, ptr %arrayidx1, align 4
|
||||||
%iv.1.next = add nsw i64 %iv.1, 1
|
%iv.1.next = add nsw i64 %iv.1, 1
|
||||||
%c.1 = icmp slt i64 %iv.1.next, 100
|
%c.1 = icmp slt i64 %iv.1.next, 100
|
||||||
br i1 %c.1, label %loop.1, label %loop.2.ph
|
br i1 %c.1, label %loop.1, label %loop.2.ph
|
||||||
|
@ -125,33 +123,32 @@ loop.2.ph:
|
||||||
|
|
||||||
loop.2:
|
loop.2:
|
||||||
%iv.2 = phi i64 [ %iv.2.next, %loop.2 ], [ 0, %loop.2.ph ]
|
%iv.2 = phi i64 [ %iv.2.next, %loop.2 ], [ 0, %loop.2.ph ]
|
||||||
%ptr.iv.2 = getelementptr inbounds [100 x i32], [100 x i32]* %A, i64 0, i64 %iv.2
|
%ptr.iv.2 = getelementptr inbounds [100 x i32], ptr %A, i64 0, i64 %iv.2
|
||||||
%l.0 = load i32, i32* %ptr.iv.2, align 4
|
%l.0 = load i32, ptr %ptr.iv.2, align 4
|
||||||
call void @use(i32 %l.0)
|
call void @use(i32 %l.0)
|
||||||
%add = add nsw i64 %iv.2, 1
|
%add = add nsw i64 %iv.2, 1
|
||||||
%ptr.iv.2.add.1 = getelementptr inbounds [100 x i32], [100 x i32]* %A, i64 0, i64 %add
|
%ptr.iv.2.add.1 = getelementptr inbounds [100 x i32], ptr %A, i64 0, i64 %add
|
||||||
store i32 10, i32* %ptr.iv.2.add.1, align 4
|
store i32 10, ptr %ptr.iv.2.add.1, align 4
|
||||||
%l.1 = load i32, i32* %ptr.iv.2, align 4
|
%l.1 = load i32, ptr %ptr.iv.2, align 4
|
||||||
call void @use(i32 %l.1)
|
call void @use(i32 %l.1)
|
||||||
%iv.2.next = add nsw i64 %iv.2, 1
|
%iv.2.next = add nsw i64 %iv.2, 1
|
||||||
%c.2 = icmp slt i64 %iv.2.next, 100
|
%c.2 = icmp slt i64 %iv.2.next, 100
|
||||||
br i1 %c.2, label %loop.2, label %exit
|
br i1 %c.2, label %loop.2, label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
call void @llvm.lifetime.end.p0i8(i64 400, i8* nonnull %A.cast) #5
|
call void @llvm.lifetime.end.p0(i64 400, ptr nonnull %A) #5
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
|
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
|
||||||
|
|
||||||
; Make sure `store i32 10, i32* %ptr.2` in %cond.store is not removed. The
|
; Make sure `store i32 10, ptr %ptr.2` in %cond.store is not removed. The
|
||||||
; stored value may be read by `%use = load i32, i32* %ptr.1` in a future
|
; stored value may be read by `%use = load i32, ptr %ptr.1` in a future
|
||||||
; iteration.
|
; iteration.
|
||||||
define void@test.3() {
|
define void@test.3() {
|
||||||
; CHECK-LABEL: @test.3(
|
; CHECK-LABEL: @test.3(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[NODESTACK:%.*]] = alloca [12 x i32], align 4
|
; CHECK-NEXT: [[NODESTACK:%.*]] = alloca [12 x i32], align 4
|
||||||
; CHECK-NEXT: [[NODESTACK_CAST:%.*]] = bitcast [12 x i32]* [[NODESTACK]] to i8*
|
|
||||||
; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond(i32 1)
|
; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond(i32 1)
|
||||||
; CHECK-NEXT: br i1 [[C_1]], label [[CLEANUP:%.*]], label [[LOOP_HEADER:%.*]]
|
; CHECK-NEXT: br i1 [[C_1]], label [[CLEANUP:%.*]], label [[LOOP_HEADER:%.*]]
|
||||||
; CHECK: loop.header:
|
; CHECK: loop.header:
|
||||||
|
@ -160,13 +157,13 @@ define void@test.3() {
|
||||||
; CHECK-NEXT: br i1 [[CMP]], label [[COND_READ:%.*]], label [[COND_STORE:%.*]]
|
; CHECK-NEXT: br i1 [[CMP]], label [[COND_READ:%.*]], label [[COND_STORE:%.*]]
|
||||||
; CHECK: cond.read:
|
; CHECK: cond.read:
|
||||||
; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[DEPTH_1]], -3
|
; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[DEPTH_1]], -3
|
||||||
; CHECK-NEXT: [[PTR_1:%.*]] = getelementptr inbounds [12 x i32], [12 x i32]* [[NODESTACK]], i32 0, i32 [[SUB]]
|
; CHECK-NEXT: [[PTR_1:%.*]] = getelementptr inbounds [12 x i32], ptr [[NODESTACK]], i32 0, i32 [[SUB]]
|
||||||
; CHECK-NEXT: [[USE:%.*]] = load i32, i32* [[PTR_1]], align 4
|
; CHECK-NEXT: [[USE:%.*]] = load i32, ptr [[PTR_1]], align 4
|
||||||
; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond(i32 [[USE]])
|
; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond(i32 [[USE]])
|
||||||
; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[COND_STORE]]
|
; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[COND_STORE]]
|
||||||
; CHECK: cond.store:
|
; CHECK: cond.store:
|
||||||
; CHECK-NEXT: [[PTR_2:%.*]] = getelementptr inbounds [12 x i32], [12 x i32]* [[NODESTACK]], i32 0, i32 [[DEPTH_1]]
|
; CHECK-NEXT: [[PTR_2:%.*]] = getelementptr inbounds [12 x i32], ptr [[NODESTACK]], i32 0, i32 [[DEPTH_1]]
|
||||||
; CHECK-NEXT: store i32 10, i32* [[PTR_2]], align 4
|
; CHECK-NEXT: store i32 10, ptr [[PTR_2]], align 4
|
||||||
; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[DEPTH_1]], 1
|
; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[DEPTH_1]], 1
|
||||||
; CHECK-NEXT: [[C_3:%.*]] = call i1 @cond(i32 20)
|
; CHECK-NEXT: [[C_3:%.*]] = call i1 @cond(i32 20)
|
||||||
; CHECK-NEXT: br i1 [[C_3]], label [[CLEANUP]], label [[LOOP_LATCH]]
|
; CHECK-NEXT: br i1 [[C_3]], label [[CLEANUP]], label [[LOOP_LATCH]]
|
||||||
|
@ -174,12 +171,11 @@ define void@test.3() {
|
||||||
; CHECK-NEXT: [[DEPTH_1_BE]] = phi i32 [ [[SUB]], [[COND_READ]] ], [ [[INC]], [[COND_STORE]] ]
|
; CHECK-NEXT: [[DEPTH_1_BE]] = phi i32 [ [[SUB]], [[COND_READ]] ], [ [[INC]], [[COND_STORE]] ]
|
||||||
; CHECK-NEXT: br label [[LOOP_HEADER]]
|
; CHECK-NEXT: br label [[LOOP_HEADER]]
|
||||||
; CHECK: cleanup:
|
; CHECK: cleanup:
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 48, i8* nonnull [[NODESTACK_CAST]])
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 48, ptr nonnull [[NODESTACK]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%nodeStack = alloca [12 x i32], align 4
|
%nodeStack = alloca [12 x i32], align 4
|
||||||
%nodeStack.cast = bitcast [12 x i32]* %nodeStack to i8*
|
|
||||||
%c.1 = call i1 @cond(i32 1)
|
%c.1 = call i1 @cond(i32 1)
|
||||||
br i1 %c.1, label %cleanup, label %loop.header
|
br i1 %c.1, label %cleanup, label %loop.header
|
||||||
|
|
||||||
|
@ -190,14 +186,14 @@ loop.header: ; preds = %entry, %while.cond
|
||||||
|
|
||||||
cond.read: ; preds = %while.cond
|
cond.read: ; preds = %while.cond
|
||||||
%sub = add nsw i32 %depth.1, -3
|
%sub = add nsw i32 %depth.1, -3
|
||||||
%ptr.1 = getelementptr inbounds [12 x i32], [12 x i32]* %nodeStack, i32 0, i32 %sub
|
%ptr.1 = getelementptr inbounds [12 x i32], ptr %nodeStack, i32 0, i32 %sub
|
||||||
%use = load i32, i32* %ptr.1, align 4
|
%use = load i32, ptr %ptr.1, align 4
|
||||||
%c.2 = call i1 @cond(i32 %use)
|
%c.2 = call i1 @cond(i32 %use)
|
||||||
br i1 %c.2, label %loop.latch, label %cond.store
|
br i1 %c.2, label %loop.latch, label %cond.store
|
||||||
|
|
||||||
cond.store:
|
cond.store:
|
||||||
%ptr.2 = getelementptr inbounds [12 x i32], [12 x i32]* %nodeStack, i32 0, i32 %depth.1
|
%ptr.2 = getelementptr inbounds [12 x i32], ptr %nodeStack, i32 0, i32 %depth.1
|
||||||
store i32 10, i32* %ptr.2, align 4
|
store i32 10, ptr %ptr.2, align 4
|
||||||
%inc = add nsw i32 %depth.1, 1
|
%inc = add nsw i32 %depth.1, 1
|
||||||
%c.3 = call i1 @cond(i32 20)
|
%c.3 = call i1 @cond(i32 20)
|
||||||
br i1 %c.3, label %cleanup, label %loop.latch
|
br i1 %c.3, label %cleanup, label %loop.latch
|
||||||
|
@ -207,7 +203,7 @@ loop.latch:
|
||||||
br label %loop.header
|
br label %loop.header
|
||||||
|
|
||||||
cleanup: ; preds = %while.body, %while.end, %entry
|
cleanup: ; preds = %while.body, %while.end, %entry
|
||||||
call void @llvm.lifetime.end.p0i8(i64 48, i8* nonnull %nodeStack.cast) #3
|
call void @llvm.lifetime.end.p0(i64 48, ptr nonnull %nodeStack) #3
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,14 +211,14 @@ define void @store_to_invariant_loc() {
|
||||||
; CHECK-LABEL: @store_to_invariant_loc(
|
; CHECK-LABEL: @store_to_invariant_loc(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca [100 x i32], align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca [100 x i32], align 4
|
||||||
; CHECK-NEXT: [[PTR_20:%.*]] = getelementptr inbounds [100 x i32], [100 x i32]* [[A]], i64 0, i64 20
|
; CHECK-NEXT: [[PTR_20:%.*]] = getelementptr inbounds [100 x i32], ptr [[A]], i64 0, i64 20
|
||||||
; CHECK-NEXT: br label [[LOOP:%.*]]
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||||||
; CHECK: loop:
|
; CHECK: loop:
|
||||||
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
|
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
|
||||||
; CHECK-NEXT: [[PTR_IV:%.*]] = getelementptr inbounds [100 x i32], [100 x i32]* [[A]], i64 0, i64 [[IV]]
|
; CHECK-NEXT: [[PTR_IV:%.*]] = getelementptr inbounds [100 x i32], ptr [[A]], i64 0, i64 [[IV]]
|
||||||
; CHECK-NEXT: [[L_0:%.*]] = load i32, i32* [[PTR_IV]], align 4
|
; CHECK-NEXT: [[L_0:%.*]] = load i32, ptr [[PTR_IV]], align 4
|
||||||
; CHECK-NEXT: call void @use(i32 [[L_0]])
|
; CHECK-NEXT: call void @use(i32 [[L_0]])
|
||||||
; CHECK-NEXT: store i32 10, i32* [[PTR_20]], align 4
|
; CHECK-NEXT: store i32 10, ptr [[PTR_20]], align 4
|
||||||
; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 1
|
; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 1
|
||||||
; CHECK-NEXT: [[C:%.*]] = icmp slt i64 [[IV_NEXT]], 100
|
; CHECK-NEXT: [[C:%.*]] = icmp slt i64 [[IV_NEXT]], 100
|
||||||
; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]]
|
; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]]
|
||||||
|
@ -231,15 +227,15 @@ define void @store_to_invariant_loc() {
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%A = alloca [100 x i32], align 4
|
%A = alloca [100 x i32], align 4
|
||||||
%ptr.20 = getelementptr inbounds [100 x i32], [100 x i32]* %A, i64 0, i64 20
|
%ptr.20 = getelementptr inbounds [100 x i32], ptr %A, i64 0, i64 20
|
||||||
br label %loop
|
br label %loop
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
%iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
|
%iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
|
||||||
%ptr.iv = getelementptr inbounds [100 x i32], [100 x i32]* %A, i64 0, i64 %iv
|
%ptr.iv = getelementptr inbounds [100 x i32], ptr %A, i64 0, i64 %iv
|
||||||
%l.0 = load i32, i32* %ptr.iv, align 4
|
%l.0 = load i32, ptr %ptr.iv, align 4
|
||||||
call void @use(i32 %l.0)
|
call void @use(i32 %l.0)
|
||||||
store i32 10, i32* %ptr.20, align 4
|
store i32 10, ptr %ptr.20, align 4
|
||||||
%iv.next = add nsw i64 %iv, 1
|
%iv.next = add nsw i64 %iv, 1
|
||||||
%c = icmp slt i64 %iv.next, 100
|
%c = icmp slt i64 %iv.next, 100
|
||||||
br i1 %c, label %loop , label %exit
|
br i1 %c, label %loop , label %exit
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,173 +4,163 @@
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||||
declare void @unknown_func()
|
declare void @unknown_func()
|
||||||
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) nounwind
|
declare void @llvm.lifetime.start.p0(i64, ptr nocapture) nounwind
|
||||||
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) nounwind
|
declare void @llvm.lifetime.end.p0(i64, ptr nocapture) nounwind
|
||||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
|
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind
|
||||||
declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
|
declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i32, i1) nounwind
|
||||||
|
|
||||||
declare noalias i8* @calloc(i64, i64) #5
|
declare noalias ptr @calloc(i64, i64) #5
|
||||||
declare noalias i8* @malloc(i64) #0
|
declare noalias ptr @malloc(i64) #0
|
||||||
declare noalias i8* @strdup(i8* nocapture readonly) #1
|
declare noalias ptr @strdup(ptr nocapture readonly) #1
|
||||||
declare void @free(i8* nocapture) #2
|
declare void @free(ptr nocapture) #2
|
||||||
|
|
||||||
define void @test16(i32* noalias %P) {
|
define void @test16(ptr noalias %P) {
|
||||||
; CHECK-LABEL: @test16(
|
; CHECK-LABEL: @test16(
|
||||||
; CHECK-NEXT: [[P2:%.*]] = bitcast i32* [[P:%.*]] to i8*
|
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB3:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB3:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: call void @free(i8* [[P2]])
|
; CHECK-NEXT: call void @free(ptr [[P:%.*]])
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%P2 = bitcast i32* %P to i8*
|
store i32 1, ptr %P
|
||||||
store i32 1, i32* %P
|
|
||||||
br i1 true, label %bb1, label %bb3
|
br i1 true, label %bb1, label %bb3
|
||||||
bb1:
|
bb1:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
call void @free(i8* %P2)
|
call void @free(ptr %P)
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; We cannot remove the store in the entry block, because @unknown_func could
|
; We cannot remove the store in the entry block, because @unknown_func could
|
||||||
; unwind and the stored value could be read by the caller.
|
; unwind and the stored value could be read by the caller.
|
||||||
define void @test17(i32* noalias %P) {
|
define void @test17(ptr noalias %P) {
|
||||||
; CHECK-LABEL: @test17(
|
; CHECK-LABEL: @test17(
|
||||||
; CHECK-NEXT: [[P2:%.*]] = bitcast i32* [[P:%.*]] to i8*
|
; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P]], align 4
|
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB3:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB3:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: call void @unknown_func()
|
; CHECK-NEXT: call void @unknown_func()
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: call void @free(i8* [[P2]])
|
; CHECK-NEXT: call void @free(ptr [[P]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%P2 = bitcast i32* %P to i8*
|
store i32 1, ptr %P
|
||||||
store i32 1, i32* %P
|
|
||||||
br i1 true, label %bb1, label %bb3
|
br i1 true, label %bb1, label %bb3
|
||||||
bb1:
|
bb1:
|
||||||
call void @unknown_func()
|
call void @unknown_func()
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
call void @free(i8* %P2)
|
call void @free(ptr %P)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test17_read_after_free(i32* noalias %P) {
|
define void @test17_read_after_free(ptr noalias %P) {
|
||||||
; CHECK-LABEL: @test17_read_after_free(
|
; CHECK-LABEL: @test17_read_after_free(
|
||||||
; CHECK-NEXT: [[P2:%.*]] = bitcast i32* [[P:%.*]] to i8*
|
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB3:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB3:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: call void @free(i8* [[P2]])
|
; CHECK-NEXT: call void @free(ptr [[P:%.*]])
|
||||||
; CHECK-NEXT: [[LV:%.*]] = load i8, i8* [[P2]], align 1
|
; CHECK-NEXT: [[LV:%.*]] = load i8, ptr [[P]], align 1
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%P2 = bitcast i32* %P to i8*
|
store i32 1, ptr %P
|
||||||
store i32 1, i32* %P
|
|
||||||
br i1 true, label %bb1, label %bb3
|
br i1 true, label %bb1, label %bb3
|
||||||
bb1:
|
bb1:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
call void @free(i8* %P2)
|
call void @free(ptr %P)
|
||||||
%lv = load i8, i8* %P2
|
%lv = load i8, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test19(i32* noalias %P) {
|
define void @test19(ptr noalias %P) {
|
||||||
; CHECK-LABEL: @test19(
|
; CHECK-LABEL: @test19(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ARRAYIDX0]], i8 0, i64 28, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i1 false)
|
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 1
|
||||||
; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX1]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX1]], align 4
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
|
%arrayidx0 = getelementptr inbounds i32, ptr %P, i64 1
|
||||||
%p3 = bitcast i32* %arrayidx0 to i8*
|
call void @llvm.memset.p0.i64(ptr %arrayidx0, i8 0, i64 28, i32 4, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
|
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
|
%arrayidx1 = getelementptr inbounds i32, ptr %P, i64 1
|
||||||
store i32 1, i32* %arrayidx1, align 4
|
store i32 1, ptr %arrayidx1, align 4
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
define void @test20(i32* noalias %P) {
|
define void @test20(ptr noalias %P) {
|
||||||
; CHECK-LABEL: @test20(
|
; CHECK-LABEL: @test20(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARRAYIDX0]], i64 4
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP0]], i8 0, i64 24, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false)
|
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 1
|
||||||
; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX1]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX1]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
|
%arrayidx0 = getelementptr inbounds i32, ptr %P, i64 1
|
||||||
%p3 = bitcast i32* %arrayidx0 to i8*
|
call void @llvm.memset.p0.i64(ptr %arrayidx0, i8 0, i64 28, i32 4, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
|
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
|
%arrayidx1 = getelementptr inbounds i32, ptr %P, i64 1
|
||||||
store i32 1, i32* %arrayidx1, align 4
|
store i32 1, ptr %arrayidx1, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define i8* @test26() {
|
define ptr @test26() {
|
||||||
; CHECK-LABEL: @test26(
|
; CHECK-LABEL: @test26(
|
||||||
; CHECK-NEXT: bb1:
|
; CHECK-NEXT: bb1:
|
||||||
; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB3:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: [[M:%.*]] = call noalias i8* @malloc(i64 10)
|
; CHECK-NEXT: [[M:%.*]] = call noalias ptr @malloc(i64 10)
|
||||||
; CHECK-NEXT: store i8 1, i8* [[M]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: [[R:%.*]] = phi i8* [ null, [[BB1:%.*]] ], [ [[M]], [[BB2]] ]
|
; CHECK-NEXT: [[R:%.*]] = phi ptr [ null, [[BB1:%.*]] ], [ [[M]], [[BB2]] ]
|
||||||
; CHECK-NEXT: ret i8* [[R]]
|
; CHECK-NEXT: ret ptr [[R]]
|
||||||
;
|
;
|
||||||
bb1:
|
bb1:
|
||||||
br i1 true, label %bb2, label %bb3
|
br i1 true, label %bb2, label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
%m = call noalias i8* @malloc(i64 10)
|
%m = call noalias ptr @malloc(i64 10)
|
||||||
store i8 1, i8* %m
|
store i8 1, ptr %m
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
%r = phi i8* [ null, %bb1 ], [ %m, %bb2 ]
|
%r = phi ptr [ null, %bb1 ], [ %m, %bb2 ]
|
||||||
ret i8* %r
|
ret ptr %r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -179,214 +169,184 @@ define void @test27() {
|
||||||
; CHECK-NEXT: bb1:
|
; CHECK-NEXT: bb1:
|
||||||
; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB3:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: [[M:%.*]] = call noalias i8* @malloc(i64 10)
|
; CHECK-NEXT: [[M:%.*]] = call noalias ptr @malloc(i64 10)
|
||||||
; CHECK-NEXT: store i8 1, i8* [[M]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: [[R:%.*]] = phi i8* [ null, [[BB1:%.*]] ], [ [[M]], [[BB2]] ]
|
; CHECK-NEXT: [[R:%.*]] = phi ptr [ null, [[BB1:%.*]] ], [ [[M]], [[BB2]] ]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
bb1:
|
bb1:
|
||||||
br i1 true, label %bb2, label %bb3
|
br i1 true, label %bb2, label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
%m = call noalias i8* @malloc(i64 10)
|
%m = call noalias ptr @malloc(i64 10)
|
||||||
store i8 1, i8* %m
|
store i8 1, ptr %m
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
%r = phi i8* [ null, %bb1 ], [ %m, %bb2 ]
|
%r = phi ptr [ null, %bb1 ], [ %m, %bb2 ]
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define i8* @test27_pointer_escape() {
|
define ptr @test27_pointer_escape() {
|
||||||
; CHECK-LABEL: @test27_pointer_escape(
|
; CHECK-LABEL: @test27_pointer_escape(
|
||||||
; CHECK-NEXT: bb1:
|
; CHECK-NEXT: bb1:
|
||||||
; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB3:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: [[M:%.*]] = call noalias i8* @malloc(i64 10)
|
; CHECK-NEXT: [[M:%.*]] = call noalias ptr @malloc(i64 10)
|
||||||
; CHECK-NEXT: store i8 1, i8* [[M]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: [[R:%.*]] = phi i8* [ null, [[BB1:%.*]] ], [ [[M]], [[BB2]] ]
|
; CHECK-NEXT: [[R:%.*]] = phi ptr [ null, [[BB1:%.*]] ], [ [[M]], [[BB2]] ]
|
||||||
; CHECK-NEXT: ret i8* [[R]]
|
; CHECK-NEXT: ret ptr [[R]]
|
||||||
;
|
;
|
||||||
bb1:
|
bb1:
|
||||||
br i1 true, label %bb2, label %bb3
|
br i1 true, label %bb2, label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
%m = call noalias i8* @malloc(i64 10)
|
%m = call noalias ptr @malloc(i64 10)
|
||||||
store i8 1, i8* %m
|
store i8 1, ptr %m
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
%r = phi i8* [ null, %bb1 ], [ %m, %bb2 ]
|
%r = phi ptr [ null, %bb1 ], [ %m, %bb2 ]
|
||||||
ret i8* %r
|
ret ptr %r
|
||||||
}
|
}
|
||||||
|
|
||||||
define i8* @test28() {
|
define ptr @test28() {
|
||||||
; CHECK-LABEL: @test28(
|
; CHECK-LABEL: @test28(
|
||||||
; CHECK-NEXT: bb0:
|
; CHECK-NEXT: bb0:
|
||||||
; CHECK-NEXT: [[M:%.*]] = call noalias i8* @malloc(i64 10)
|
; CHECK-NEXT: [[M:%.*]] = call noalias ptr @malloc(i64 10)
|
||||||
; CHECK-NEXT: [[MC0:%.*]] = bitcast i8* [[M]] to i8*
|
; CHECK-NEXT: store i8 2, ptr [[M]], align 1
|
||||||
; CHECK-NEXT: [[MC1:%.*]] = bitcast i8* [[MC0]] to i8*
|
; CHECK-NEXT: ret ptr [[M]]
|
||||||
; CHECK-NEXT: [[MC2:%.*]] = bitcast i8* [[MC1]] to i8*
|
|
||||||
; CHECK-NEXT: [[MC3:%.*]] = bitcast i8* [[MC2]] to i8*
|
|
||||||
; CHECK-NEXT: [[MC4:%.*]] = bitcast i8* [[MC3]] to i8*
|
|
||||||
; CHECK-NEXT: [[MC5:%.*]] = bitcast i8* [[MC4]] to i8*
|
|
||||||
; CHECK-NEXT: [[MC6:%.*]] = bitcast i8* [[MC5]] to i8*
|
|
||||||
; CHECK-NEXT: [[M0:%.*]] = bitcast i8* [[MC6]] to i8*
|
|
||||||
; CHECK-NEXT: store i8 2, i8* [[M]], align 1
|
|
||||||
; CHECK-NEXT: ret i8* [[M0]]
|
|
||||||
;
|
;
|
||||||
bb0:
|
bb0:
|
||||||
%m = call noalias i8* @malloc(i64 10)
|
%m = call noalias ptr @malloc(i64 10)
|
||||||
%mc0 = bitcast i8* %m to i8*
|
store i8 2, ptr %m
|
||||||
%mc1 = bitcast i8* %mc0 to i8*
|
ret ptr %m
|
||||||
%mc2 = bitcast i8* %mc1 to i8*
|
|
||||||
%mc3 = bitcast i8* %mc2 to i8*
|
|
||||||
%mc4 = bitcast i8* %mc3 to i8*
|
|
||||||
%mc5 = bitcast i8* %mc4 to i8*
|
|
||||||
%mc6 = bitcast i8* %mc5 to i8*
|
|
||||||
%m0 = bitcast i8* %mc6 to i8*
|
|
||||||
store i8 2, i8* %m
|
|
||||||
ret i8* %m0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
%struct.SystemCallMapElementStruct = type { i8*, i32, %struct.NodePtrVecStruct* }
|
%struct.SystemCallMapElementStruct = type { ptr, i32, ptr }
|
||||||
%struct.NodePtrVecStruct = type { i32, i32, %struct.NodeStruct** }
|
%struct.NodePtrVecStruct = type { i32, i32, ptr }
|
||||||
%struct.NodeStruct = type { i32, i32, i8*, i32, i32, %struct.NodeStruct*, %struct.NodeListStruct*, %struct.EdgeListStruct*, i32, i32 }
|
%struct.NodeStruct = type { i32, i32, ptr, i32, i32, ptr, ptr, ptr, i32, i32 }
|
||||||
%struct.NodeListStruct = type { %struct.NodeStruct*, %struct.NodeListStruct* }
|
%struct.NodeListStruct = type { ptr, ptr }
|
||||||
%struct.EdgeListStruct = type { i32, %struct.NodeStruct*, %struct.EdgeListStruct* }
|
%struct.EdgeListStruct = type { i32, ptr, ptr }
|
||||||
%struct.SystemCallMapStruct = type { i32, i32, %struct.SystemCallMapElementStruct** }
|
%struct.SystemCallMapStruct = type { i32, i32, ptr }
|
||||||
|
|
||||||
declare %struct.NodePtrVecStruct* @NodePtrVec_new(i32)
|
declare ptr @NodePtrVec_new(i32)
|
||||||
|
|
||||||
define noalias %struct.SystemCallMapElementStruct* @SystemCallMapElement_new(i8* nocapture readonly %label, i32 %initialSize) {
|
define noalias ptr @SystemCallMapElement_new(ptr nocapture readonly %label, i32 %initialSize) {
|
||||||
; CHECK-LABEL: @SystemCallMapElement_new(
|
; CHECK-LABEL: @SystemCallMapElement_new(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = tail call dereferenceable_or_null(24) i8* @malloc(i64 24) #[[ATTR7:[0-9]+]]
|
; CHECK-NEXT: [[CALL:%.*]] = tail call dereferenceable_or_null(24) ptr @malloc(i64 24) #[[ATTR7:[0-9]+]]
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to %struct.SystemCallMapElementStruct*
|
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq ptr [[CALL]], null
|
||||||
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8* [[CALL]], null
|
|
||||||
; CHECK-NEXT: br i1 [[TOBOOL]], label [[CLEANUP:%.*]], label [[IF_THEN:%.*]]
|
; CHECK-NEXT: br i1 [[TOBOOL]], label [[CLEANUP:%.*]], label [[IF_THEN:%.*]]
|
||||||
; CHECK: if.then:
|
; CHECK: if.then:
|
||||||
; CHECK-NEXT: [[CALL1:%.*]] = tail call i8* @strdup(i8* [[LABEL:%.*]])
|
; CHECK-NEXT: [[CALL1:%.*]] = tail call ptr @strdup(ptr [[LABEL:%.*]])
|
||||||
; CHECK-NEXT: [[LABEL2:%.*]] = bitcast i8* [[CALL]] to i8**
|
; CHECK-NEXT: store ptr [[CALL1]], ptr [[CALL]], align 8
|
||||||
; CHECK-NEXT: store i8* [[CALL1]], i8** [[LABEL2]], align 8
|
; CHECK-NEXT: [[INDEX:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8
|
||||||
; CHECK-NEXT: [[INDEX:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 8
|
; CHECK-NEXT: store i32 -1, ptr [[INDEX]], align 8
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[INDEX]] to i32*
|
; CHECK-NEXT: [[TOBOOL4:%.*]] = icmp eq ptr [[CALL1]], null
|
||||||
; CHECK-NEXT: store i32 -1, i32* [[TMP1]], align 8
|
|
||||||
; CHECK-NEXT: [[TOBOOL4:%.*]] = icmp eq i8* [[CALL1]], null
|
|
||||||
; CHECK-NEXT: br i1 [[TOBOOL4]], label [[IF_THEN5:%.*]], label [[IF_END:%.*]]
|
; CHECK-NEXT: br i1 [[TOBOOL4]], label [[IF_THEN5:%.*]], label [[IF_END:%.*]]
|
||||||
; CHECK: if.then5:
|
; CHECK: if.then5:
|
||||||
; CHECK-NEXT: tail call void @free(i8* nonnull [[CALL]])
|
; CHECK-NEXT: tail call void @free(ptr nonnull [[CALL]])
|
||||||
; CHECK-NEXT: br label [[CLEANUP]]
|
; CHECK-NEXT: br label [[CLEANUP]]
|
||||||
; CHECK: if.end:
|
; CHECK: if.end:
|
||||||
; CHECK-NEXT: [[CALL6:%.*]] = tail call %struct.NodePtrVecStruct* @NodePtrVec_new(i32 [[INITIALSIZE:%.*]]) #[[ATTR5:[0-9]+]]
|
; CHECK-NEXT: [[CALL6:%.*]] = tail call ptr @NodePtrVec_new(i32 [[INITIALSIZE:%.*]]) #[[ATTR5:[0-9]+]]
|
||||||
; CHECK-NEXT: [[NODES:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 16
|
; CHECK-NEXT: [[NODES:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 16
|
||||||
; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[NODES]] to %struct.NodePtrVecStruct**
|
; CHECK-NEXT: store ptr [[CALL6]], ptr [[NODES]], align 8
|
||||||
; CHECK-NEXT: store %struct.NodePtrVecStruct* [[CALL6]], %struct.NodePtrVecStruct** [[TMP2]], align 8
|
; CHECK-NEXT: [[TOBOOL8:%.*]] = icmp eq ptr [[CALL6]], null
|
||||||
; CHECK-NEXT: [[TOBOOL8:%.*]] = icmp eq %struct.NodePtrVecStruct* [[CALL6]], null
|
|
||||||
; CHECK-NEXT: br i1 [[TOBOOL8]], label [[IF_THEN9:%.*]], label [[CLEANUP]]
|
; CHECK-NEXT: br i1 [[TOBOOL8]], label [[IF_THEN9:%.*]], label [[CLEANUP]]
|
||||||
; CHECK: if.then9:
|
; CHECK: if.then9:
|
||||||
; CHECK-NEXT: tail call void @free(i8* nonnull [[CALL]])
|
; CHECK-NEXT: tail call void @free(ptr nonnull [[CALL]])
|
||||||
; CHECK-NEXT: br label [[CLEANUP]]
|
; CHECK-NEXT: br label [[CLEANUP]]
|
||||||
; CHECK: cleanup:
|
; CHECK: cleanup:
|
||||||
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi %struct.SystemCallMapElementStruct* [ null, [[IF_THEN9]] ], [ null, [[IF_THEN5]] ], [ [[TMP0]], [[IF_END]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
|
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi ptr [ null, [[IF_THEN9]] ], [ null, [[IF_THEN5]] ], [ [[CALL]], [[IF_END]] ], [ [[CALL]], [[ENTRY:%.*]] ]
|
||||||
; CHECK-NEXT: ret %struct.SystemCallMapElementStruct* [[RETVAL_0]]
|
; CHECK-NEXT: ret ptr [[RETVAL_0]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%call = tail call dereferenceable_or_null(24) i8* @malloc(i64 24) #4
|
%call = tail call dereferenceable_or_null(24) ptr @malloc(i64 24) #4
|
||||||
%0 = bitcast i8* %call to %struct.SystemCallMapElementStruct*
|
%tobool = icmp eq ptr %call, null
|
||||||
%tobool = icmp eq i8* %call, null
|
|
||||||
br i1 %tobool, label %cleanup, label %if.then
|
br i1 %tobool, label %cleanup, label %if.then
|
||||||
|
|
||||||
if.then: ; preds = %entry
|
if.then: ; preds = %entry
|
||||||
%call1 = tail call i8* @strdup(i8* %label)
|
%call1 = tail call ptr @strdup(ptr %label)
|
||||||
%label2 = bitcast i8* %call to i8**
|
store ptr %call1, ptr %call, align 8
|
||||||
store i8* %call1, i8** %label2, align 8
|
%index = getelementptr inbounds i8, ptr %call, i64 8
|
||||||
%index = getelementptr inbounds i8, i8* %call, i64 8
|
store i32 -1, ptr %index, align 8
|
||||||
%1 = bitcast i8* %index to i32*
|
%tobool4 = icmp eq ptr %call1, null
|
||||||
store i32 -1, i32* %1, align 8
|
|
||||||
%tobool4 = icmp eq i8* %call1, null
|
|
||||||
br i1 %tobool4, label %if.then5, label %if.end
|
br i1 %tobool4, label %if.then5, label %if.end
|
||||||
|
|
||||||
if.then5: ; preds = %if.then
|
if.then5: ; preds = %if.then
|
||||||
tail call void @free(i8* nonnull %call)
|
tail call void @free(ptr nonnull %call)
|
||||||
br label %cleanup
|
br label %cleanup
|
||||||
|
|
||||||
if.end: ; preds = %if.then
|
if.end: ; preds = %if.then
|
||||||
%call6 = tail call %struct.NodePtrVecStruct* @NodePtrVec_new(i32 %initialSize) #2
|
%call6 = tail call ptr @NodePtrVec_new(i32 %initialSize) #2
|
||||||
%nodes = getelementptr inbounds i8, i8* %call, i64 16
|
%nodes = getelementptr inbounds i8, ptr %call, i64 16
|
||||||
%2 = bitcast i8* %nodes to %struct.NodePtrVecStruct**
|
store ptr %call6, ptr %nodes, align 8
|
||||||
store %struct.NodePtrVecStruct* %call6, %struct.NodePtrVecStruct** %2, align 8
|
%tobool8 = icmp eq ptr %call6, null
|
||||||
%tobool8 = icmp eq %struct.NodePtrVecStruct* %call6, null
|
|
||||||
br i1 %tobool8, label %if.then9, label %cleanup
|
br i1 %tobool8, label %if.then9, label %cleanup
|
||||||
|
|
||||||
if.then9: ; preds = %if.end
|
if.then9: ; preds = %if.end
|
||||||
tail call void @free(i8* nonnull %call)
|
tail call void @free(ptr nonnull %call)
|
||||||
br label %cleanup
|
br label %cleanup
|
||||||
|
|
||||||
cleanup: ; preds = %entry, %if.end, %if.then9, %if.then5
|
cleanup: ; preds = %entry, %if.end, %if.then9, %if.then5
|
||||||
%retval.0 = phi %struct.SystemCallMapElementStruct* [ null, %if.then9 ], [ null, %if.then5 ], [ %0, %if.end ], [ %0, %entry ]
|
%retval.0 = phi ptr [ null, %if.then9 ], [ null, %if.then5 ], [ %call, %if.end ], [ %call, %entry ]
|
||||||
ret %struct.SystemCallMapElementStruct* %retval.0
|
ret ptr %retval.0
|
||||||
}
|
}
|
||||||
|
|
||||||
%struct.BitfieldStruct = type { i32, i8* }
|
%struct.BitfieldStruct = type { i32, ptr }
|
||||||
|
|
||||||
define noalias %struct.BitfieldStruct* @Bitfield_new(i32 %bitsNeeded) {
|
define noalias ptr @Bitfield_new(i32 %bitsNeeded) {
|
||||||
; CHECK-LABEL: @Bitfield_new(
|
; CHECK-LABEL: @Bitfield_new(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = tail call dereferenceable_or_null(16) i8* @malloc(i64 16) #[[ATTR7]]
|
; CHECK-NEXT: [[CALL:%.*]] = tail call dereferenceable_or_null(16) ptr @malloc(i64 16) #[[ATTR7]]
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to %struct.BitfieldStruct*
|
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq ptr [[CALL]], null
|
||||||
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8* [[CALL]], null
|
|
||||||
; CHECK-NEXT: br i1 [[TOBOOL]], label [[CLEANUP:%.*]], label [[IF_END:%.*]]
|
; CHECK-NEXT: br i1 [[TOBOOL]], label [[CLEANUP:%.*]], label [[IF_END:%.*]]
|
||||||
; CHECK: if.end:
|
; CHECK: if.end:
|
||||||
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[BITSNEEDED:%.*]], 7
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[BITSNEEDED:%.*]], 7
|
||||||
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[ADD]], 8
|
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[ADD]], 8
|
||||||
; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[DIV]] to i64
|
; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[DIV]] to i64
|
||||||
; CHECK-NEXT: [[CALL1:%.*]] = tail call i8* @calloc(i64 [[CONV]], i64 1) #[[ATTR8:[0-9]+]]
|
; CHECK-NEXT: [[CALL1:%.*]] = tail call ptr @calloc(i64 [[CONV]], i64 1) #[[ATTR8:[0-9]+]]
|
||||||
; CHECK-NEXT: [[BITFIELD:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 8
|
; CHECK-NEXT: [[BITFIELD:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[BITFIELD]] to i8**
|
; CHECK-NEXT: store ptr [[CALL1]], ptr [[BITFIELD]], align 8
|
||||||
; CHECK-NEXT: store i8* [[CALL1]], i8** [[TMP1]], align 8
|
; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq ptr [[CALL1]], null
|
||||||
; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i8* [[CALL1]], null
|
|
||||||
; CHECK-NEXT: br i1 [[TOBOOL3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]]
|
; CHECK-NEXT: br i1 [[TOBOOL3]], label [[IF_THEN4:%.*]], label [[IF_END5:%.*]]
|
||||||
; CHECK: if.then4:
|
; CHECK: if.then4:
|
||||||
; CHECK-NEXT: tail call void @free(i8* nonnull [[CALL]])
|
; CHECK-NEXT: tail call void @free(ptr nonnull [[CALL]])
|
||||||
; CHECK-NEXT: br label [[CLEANUP]]
|
; CHECK-NEXT: br label [[CLEANUP]]
|
||||||
; CHECK: if.end5:
|
; CHECK: if.end5:
|
||||||
; CHECK-NEXT: [[BITSNEEDED6:%.*]] = bitcast i8* [[CALL]] to i32*
|
; CHECK-NEXT: store i32 [[BITSNEEDED]], ptr [[CALL]], align 8
|
||||||
; CHECK-NEXT: store i32 [[BITSNEEDED]], i32* [[BITSNEEDED6]], align 8
|
|
||||||
; CHECK-NEXT: br label [[CLEANUP]]
|
; CHECK-NEXT: br label [[CLEANUP]]
|
||||||
; CHECK: cleanup:
|
; CHECK: cleanup:
|
||||||
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi %struct.BitfieldStruct* [ [[TMP0]], [[IF_END5]] ], [ null, [[IF_THEN4]] ], [ null, [[ENTRY:%.*]] ]
|
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi ptr [ [[CALL]], [[IF_END5]] ], [ null, [[IF_THEN4]] ], [ null, [[ENTRY:%.*]] ]
|
||||||
; CHECK-NEXT: ret %struct.BitfieldStruct* [[RETVAL_0]]
|
; CHECK-NEXT: ret ptr [[RETVAL_0]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%call = tail call dereferenceable_or_null(16) i8* @malloc(i64 16) #4
|
%call = tail call dereferenceable_or_null(16) ptr @malloc(i64 16) #4
|
||||||
%0 = bitcast i8* %call to %struct.BitfieldStruct*
|
%tobool = icmp eq ptr %call, null
|
||||||
%tobool = icmp eq i8* %call, null
|
|
||||||
br i1 %tobool, label %cleanup, label %if.end
|
br i1 %tobool, label %cleanup, label %if.end
|
||||||
|
|
||||||
if.end: ; preds = %entry
|
if.end: ; preds = %entry
|
||||||
%add = add nsw i32 %bitsNeeded, 7
|
%add = add nsw i32 %bitsNeeded, 7
|
||||||
%div = sdiv i32 %add, 8
|
%div = sdiv i32 %add, 8
|
||||||
%conv = sext i32 %div to i64
|
%conv = sext i32 %div to i64
|
||||||
%call1 = tail call i8* @calloc(i64 %conv, i64 1) #3
|
%call1 = tail call ptr @calloc(i64 %conv, i64 1) #3
|
||||||
%bitfield = getelementptr inbounds i8, i8* %call, i64 8
|
%bitfield = getelementptr inbounds i8, ptr %call, i64 8
|
||||||
%1 = bitcast i8* %bitfield to i8**
|
store ptr %call1, ptr %bitfield, align 8
|
||||||
store i8* %call1, i8** %1, align 8
|
%tobool3 = icmp eq ptr %call1, null
|
||||||
%tobool3 = icmp eq i8* %call1, null
|
|
||||||
br i1 %tobool3, label %if.then4, label %if.end5
|
br i1 %tobool3, label %if.then4, label %if.end5
|
||||||
|
|
||||||
if.then4: ; preds = %if.end
|
if.then4: ; preds = %if.end
|
||||||
tail call void @free(i8* nonnull %call)
|
tail call void @free(ptr nonnull %call)
|
||||||
br label %cleanup
|
br label %cleanup
|
||||||
|
|
||||||
if.end5: ; preds = %if.end
|
if.end5: ; preds = %if.end
|
||||||
%bitsNeeded6 = bitcast i8* %call to i32*
|
store i32 %bitsNeeded, ptr %call, align 8
|
||||||
store i32 %bitsNeeded, i32* %bitsNeeded6, align 8
|
|
||||||
br label %cleanup
|
br label %cleanup
|
||||||
|
|
||||||
cleanup: ; preds = %entry, %if.end5, %if.then4
|
cleanup: ; preds = %entry, %if.end5, %if.then4
|
||||||
%retval.0 = phi %struct.BitfieldStruct* [ %0, %if.end5 ], [ null, %if.then4 ], [ null, %entry ]
|
%retval.0 = phi ptr [ %call, %if.end5 ], [ null, %if.then4 ], [ null, %entry ]
|
||||||
ret %struct.BitfieldStruct* %retval.0
|
ret ptr %retval.0
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes #0 = { nofree nounwind allocsize(0) allockind("alloc,uninitialized") }
|
attributes #0 = { nofree nounwind allocsize(0) allockind("alloc,uninitialized") }
|
||||||
|
|
|
@ -3,40 +3,38 @@
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||||
declare void @unknown_func()
|
declare void @unknown_func()
|
||||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
|
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind
|
||||||
declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
|
declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i32, i1) nounwind
|
||||||
|
|
||||||
; Tests where the pointer/object is accessible after the function returns.
|
; Tests where the pointer/object is accessible after the function returns.
|
||||||
|
|
||||||
; Overwriting store along one path to the exit.
|
; Overwriting store along one path to the exit.
|
||||||
define void @accessible_after_return_1(i32* noalias %P, i1 %c) {
|
define void @accessible_after_return_1(ptr noalias %P, i1 %c) {
|
||||||
; CHECK-LABEL: @accessible_after_return_1(
|
; CHECK-LABEL: @accessible_after_return_1(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ARRAYIDX0]], i8 0, i64 28, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i1 false)
|
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 1
|
||||||
; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX1]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX1]], align 4
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
|
%arrayidx0 = getelementptr inbounds i32, ptr %P, i64 1
|
||||||
%p3 = bitcast i32* %arrayidx0 to i8*
|
call void @llvm.memset.p0.i64(ptr %arrayidx0, i8 0, i64 28, i32 4, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
|
|
||||||
br i1 %c, label %bb1, label %bb2
|
br i1 %c, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
|
%arrayidx1 = getelementptr inbounds i32, ptr %P, i64 1
|
||||||
store i32 1, i32* %arrayidx1, align 4
|
store i32 1, ptr %arrayidx1, align 4
|
||||||
br label %bb3
|
br label %bb3
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
|
@ -45,38 +43,36 @@ bb3:
|
||||||
|
|
||||||
; Post-dominating store.
|
; Post-dominating store.
|
||||||
; TODO: The memset can be shortened.
|
; TODO: The memset can be shortened.
|
||||||
define void @accessible_after_return_2(i32* noalias %P, i1 %c) {
|
define void @accessible_after_return_2(ptr noalias %P, i1 %c) {
|
||||||
; CHECK-LABEL: @accessible_after_return_2(
|
; CHECK-LABEL: @accessible_after_return_2(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ARRAYIDX0]], i8 0, i64 28, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i1 false)
|
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 1
|
||||||
; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX1]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX1]], align 4
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 1
|
||||||
; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX2]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX2]], align 4
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
|
%arrayidx0 = getelementptr inbounds i32, ptr %P, i64 1
|
||||||
%p3 = bitcast i32* %arrayidx0 to i8*
|
call void @llvm.memset.p0.i64(ptr %arrayidx0, i8 0, i64 28, i32 4, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
|
|
||||||
br i1 %c, label %bb1, label %bb2
|
br i1 %c, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
|
%arrayidx1 = getelementptr inbounds i32, ptr %P, i64 1
|
||||||
store i32 1, i32* %arrayidx1, align 4
|
store i32 1, ptr %arrayidx1, align 4
|
||||||
br label %bb3
|
br label %bb3
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
%arrayidx2 = getelementptr inbounds i32, i32* %P, i64 1
|
%arrayidx2 = getelementptr inbounds i32, ptr %P, i64 1
|
||||||
store i32 1, i32* %arrayidx2, align 4
|
store i32 1, ptr %arrayidx2, align 4
|
||||||
br label %bb3
|
br label %bb3
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
|
@ -84,27 +80,25 @@ bb3:
|
||||||
}
|
}
|
||||||
|
|
||||||
; Stores along both exit paths.
|
; Stores along both exit paths.
|
||||||
define void @accessible_after_return_3(i32* noalias %P, i1 %c) {
|
define void @accessible_after_return_3(ptr noalias %P, i1 %c) {
|
||||||
; CHECK-LABEL: @accessible_after_return_3(
|
; CHECK-LABEL: @accessible_after_return_3(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
|
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[ARRAYIDX0]], i64 4
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[P3]], i64 4
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP0]], i8 0, i64 24, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP0]], i8 0, i64 24, i1 false)
|
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 1
|
||||||
; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX1]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[ARRAYIDX1]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
|
%arrayidx0 = getelementptr inbounds i32, ptr %P, i64 1
|
||||||
%p3 = bitcast i32* %arrayidx0 to i8*
|
call void @llvm.memset.p0.i64(ptr %arrayidx0, i8 0, i64 28, i32 4, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
|
|
||||||
br i1 %c, label %bb1, label %bb2
|
br i1 %c, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
|
@ -114,13 +108,13 @@ bb2:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
|
%arrayidx1 = getelementptr inbounds i32, ptr %P, i64 1
|
||||||
store i32 1, i32* %arrayidx1, align 4
|
store i32 1, ptr %arrayidx1, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
declare void @readonly_use(i32* nocapture) readonly
|
declare void @readonly_use(ptr nocapture) readonly
|
||||||
|
|
||||||
; Tests where the pointer/object is *NOT* accessible after the function returns.
|
; Tests where the pointer/object is *NOT* accessible after the function returns.
|
||||||
|
|
||||||
|
@ -129,11 +123,9 @@ define void @alloca_1(i1 %c) {
|
||||||
; CHECK-LABEL: @alloca_1(
|
; CHECK-LABEL: @alloca_1(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P_ALLOCA:%.*]] = alloca [32 x i32], align 4
|
; CHECK-NEXT: [[P_ALLOCA:%.*]] = alloca [32 x i32], align 4
|
||||||
; CHECK-NEXT: [[P:%.*]] = bitcast [32 x i32]* [[P_ALLOCA]] to i32*
|
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P_ALLOCA]], i64 1
|
||||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ARRAYIDX0]], i8 0, i64 28, i1 false)
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
|
; CHECK-NEXT: call void @readonly_use(ptr [[P_ALLOCA]])
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i1 false)
|
|
||||||
; CHECK-NEXT: call void @readonly_use(i32* [[P]])
|
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
|
@ -144,19 +136,17 @@ define void @alloca_1(i1 %c) {
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%P.alloca = alloca [32 x i32]
|
%P.alloca = alloca [32 x i32]
|
||||||
%P = bitcast [32 x i32]* %P.alloca to i32*
|
%arrayidx0 = getelementptr inbounds i32, ptr %P.alloca, i64 1
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
|
call void @llvm.memset.p0.i64(ptr %arrayidx0, i8 0, i64 28, i32 4, i1 false)
|
||||||
%p3 = bitcast i32* %arrayidx0 to i8*
|
call void @readonly_use(ptr %P.alloca)
|
||||||
call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
|
|
||||||
call void @readonly_use(i32* %P)
|
|
||||||
br i1 %c, label %bb1, label %bb2
|
br i1 %c, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
|
%arrayidx1 = getelementptr inbounds i32, ptr %P.alloca, i64 1
|
||||||
store i32 1, i32* %arrayidx1, align 4
|
store i32 1, ptr %arrayidx1, align 4
|
||||||
br label %bb3
|
br label %bb3
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
|
@ -168,11 +158,9 @@ define void @alloca_2(i1 %c) {
|
||||||
; CHECK-LABEL: @alloca_2(
|
; CHECK-LABEL: @alloca_2(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P_ALLOCA:%.*]] = alloca [32 x i32], align 4
|
; CHECK-NEXT: [[P_ALLOCA:%.*]] = alloca [32 x i32], align 4
|
||||||
; CHECK-NEXT: [[P:%.*]] = bitcast [32 x i32]* [[P_ALLOCA]] to i32*
|
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, ptr [[P_ALLOCA]], i64 1
|
||||||
; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 1
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[ARRAYIDX0]], i8 0, i64 28, i1 false)
|
||||||
; CHECK-NEXT: [[P3:%.*]] = bitcast i32* [[ARRAYIDX0]] to i8*
|
; CHECK-NEXT: call void @readonly_use(ptr [[P_ALLOCA]])
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 4 [[P3]], i8 0, i64 28, i1 false)
|
|
||||||
; CHECK-NEXT: call void @readonly_use(i32* [[P]])
|
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
|
@ -183,21 +171,19 @@ define void @alloca_2(i1 %c) {
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%P.alloca = alloca [32 x i32]
|
%P.alloca = alloca [32 x i32]
|
||||||
%P = bitcast [32 x i32]* %P.alloca to i32*
|
%arrayidx0 = getelementptr inbounds i32, ptr %P.alloca, i64 1
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
|
call void @llvm.memset.p0.i64(ptr %arrayidx0, i8 0, i64 28, i32 4, i1 false)
|
||||||
%p3 = bitcast i32* %arrayidx0 to i8*
|
call void @readonly_use(ptr %P.alloca)
|
||||||
call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
|
|
||||||
call void @readonly_use(i32* %P)
|
|
||||||
br i1 %c, label %bb1, label %bb2
|
br i1 %c, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
|
%arrayidx1 = getelementptr inbounds i32, ptr %P.alloca, i64 1
|
||||||
store i32 1, i32* %arrayidx1, align 4
|
store i32 1, ptr %arrayidx1, align 4
|
||||||
br label %bb3
|
br label %bb3
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
%arrayidx2 = getelementptr inbounds i32, i32* %P, i64 1
|
%arrayidx2 = getelementptr inbounds i32, ptr %P.alloca, i64 1
|
||||||
store i32 1, i32* %arrayidx2, align 4
|
store i32 1, ptr %arrayidx2, align 4
|
||||||
br label %bb3
|
br label %bb3
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
|
@ -218,10 +204,8 @@ define void @alloca_3(i1 %c) {
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%P.alloca = alloca [32 x i32]
|
%P.alloca = alloca [32 x i32]
|
||||||
%P = bitcast [32 x i32]* %P.alloca to i32*
|
%arrayidx0 = getelementptr inbounds i32, ptr %P.alloca, i64 1
|
||||||
%arrayidx0 = getelementptr inbounds i32, i32* %P, i64 1
|
call void @llvm.memset.p0.i64(ptr %arrayidx0, i8 0, i64 28, i32 4, i1 false)
|
||||||
%p3 = bitcast i32* %arrayidx0 to i8*
|
|
||||||
call void @llvm.memset.p0i8.i64(i8* %p3, i8 0, i64 28, i32 4, i1 false)
|
|
||||||
br i1 %c, label %bb1, label %bb2
|
br i1 %c, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
|
@ -231,7 +215,7 @@ bb2:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
%arrayidx1 = getelementptr inbounds i32, i32* %P, i64 1
|
%arrayidx1 = getelementptr inbounds i32, ptr %P.alloca, i64 1
|
||||||
store i32 1, i32* %arrayidx1, align 4
|
store i32 1, ptr %arrayidx1, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,32 +4,32 @@
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||||
|
|
||||||
|
|
||||||
define void @test4(i32* noalias %P) {
|
define void @test4(ptr noalias %P) {
|
||||||
; CHECK-LABEL: @test4(
|
; CHECK-LABEL: @test4(
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[P]], align 4
|
; CHECK-NEXT: [[X:%.*]] = load i32, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
%x = load i32, i32* %P
|
%x = load i32, ptr %P
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test5(i32* noalias %P) {
|
define void @test5(ptr noalias %P) {
|
||||||
; CHECK-LABEL: @test5(
|
; CHECK-LABEL: @test5(
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
|
@ -37,48 +37,48 @@ define void @test5(i32* noalias %P) {
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test8(i32* %P, i32* %Q) {
|
define void @test8(ptr %P, ptr %Q) {
|
||||||
; CHECK-LABEL: @test8(
|
; CHECK-LABEL: @test8(
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: store i32 1, i32* [[Q:%.*]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[Q:%.*]], align 4
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
store i32 1, i32* %Q
|
store i32 1, ptr %Q
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test10(i32* noalias %P) {
|
define void @test10(ptr noalias %P) {
|
||||||
; CHECK-LABEL: @test10(
|
; CHECK-LABEL: @test10(
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
|
@ -87,22 +87,21 @@ define void @test10(i32* noalias %P) {
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%P2 = bitcast i32* %P to i8*
|
store i32 0, ptr %P
|
||||||
store i32 0, i32* %P
|
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
store i8 1, i8* %P2
|
store i8 1, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @hoge()
|
declare void @hoge()
|
||||||
|
|
||||||
; Check a function with a MemoryPhi with 3 incoming values.
|
; Check a function with a MemoryPhi with 3 incoming values.
|
||||||
define void @widget(i32* %Ptr, i1 %c1, i1 %c2, i32 %v1, i32 %v2, i32 %v3) {
|
define void @widget(ptr %Ptr, i1 %c1, i1 %c2, i32 %v1, i32 %v2, i32 %v3) {
|
||||||
; CHECK-LABEL: @widget(
|
; CHECK-LABEL: @widget(
|
||||||
; CHECK-NEXT: bb:
|
; CHECK-NEXT: bb:
|
||||||
; CHECK-NEXT: tail call void @hoge()
|
; CHECK-NEXT: tail call void @hoge()
|
||||||
|
@ -120,13 +119,13 @@ define void @widget(i32* %Ptr, i1 %c1, i1 %c2, i32 %v1, i32 %v2, i32 %v3) {
|
||||||
; CHECK-NEXT: i32 2, label [[BB7:%.*]]
|
; CHECK-NEXT: i32 2, label [[BB7:%.*]]
|
||||||
; CHECK-NEXT: ]
|
; CHECK-NEXT: ]
|
||||||
; CHECK: bb5:
|
; CHECK: bb5:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[PTR:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[PTR:%.*]], align 4
|
||||||
; CHECK-NEXT: br label [[BB8]]
|
; CHECK-NEXT: br label [[BB8]]
|
||||||
; CHECK: bb6:
|
; CHECK: bb6:
|
||||||
; CHECK-NEXT: store i32 1, i32* [[PTR]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[PTR]], align 4
|
||||||
; CHECK-NEXT: br label [[BB8]]
|
; CHECK-NEXT: br label [[BB8]]
|
||||||
; CHECK: bb7:
|
; CHECK: bb7:
|
||||||
; CHECK-NEXT: store i32 2, i32* [[PTR]], align 4
|
; CHECK-NEXT: store i32 2, ptr [[PTR]], align 4
|
||||||
; CHECK-NEXT: br label [[BB8]]
|
; CHECK-NEXT: br label [[BB8]]
|
||||||
; CHECK: bb8:
|
; CHECK: bb8:
|
||||||
; CHECK-NEXT: br label [[BB4]]
|
; CHECK-NEXT: br label [[BB4]]
|
||||||
|
@ -139,7 +138,7 @@ bb1: ; preds = %bb
|
||||||
br i1 %c2, label %bb2, label %bb3
|
br i1 %c2, label %bb2, label %bb3
|
||||||
|
|
||||||
bb2: ; preds = %bb1
|
bb2: ; preds = %bb1
|
||||||
store i32 -1, i32* %Ptr, align 4
|
store i32 -1, ptr %Ptr, align 4
|
||||||
br label %bb3
|
br label %bb3
|
||||||
|
|
||||||
bb3: ; preds = %bb2, %bb1, %bb
|
bb3: ; preds = %bb2, %bb1, %bb
|
||||||
|
@ -153,15 +152,15 @@ bb4: ; preds = %bb8, %bb3
|
||||||
]
|
]
|
||||||
|
|
||||||
bb5: ; preds = %bb4
|
bb5: ; preds = %bb4
|
||||||
store i32 0, i32* %Ptr, align 4
|
store i32 0, ptr %Ptr, align 4
|
||||||
br label %bb8
|
br label %bb8
|
||||||
|
|
||||||
bb6: ; preds = %bb4
|
bb6: ; preds = %bb4
|
||||||
store i32 1, i32* %Ptr, align 4
|
store i32 1, ptr %Ptr, align 4
|
||||||
br label %bb8
|
br label %bb8
|
||||||
|
|
||||||
bb7: ; preds = %bb4
|
bb7: ; preds = %bb4
|
||||||
store i32 2, i32* %Ptr, align 4
|
store i32 2, ptr %Ptr, align 4
|
||||||
br label %bb8
|
br label %bb8
|
||||||
|
|
||||||
bb8: ; preds = %bb7, %bb6, %bb5, %bb4
|
bb8: ; preds = %bb7, %bb6, %bb5, %bb4
|
||||||
|
@ -172,7 +171,7 @@ bb8: ; preds = %bb7, %bb6, %bb5, %b
|
||||||
declare void @fn1_test11()
|
declare void @fn1_test11()
|
||||||
declare void @fn2_test11()
|
declare void @fn2_test11()
|
||||||
|
|
||||||
define void @test11(i1 %c, i8** %ptr.1) {
|
define void @test11(i1 %c, ptr %ptr.1) {
|
||||||
; CHECK-LABEL: @test11(
|
; CHECK-LABEL: @test11(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[EXIT:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[EXIT:%.*]]
|
||||||
|
@ -180,7 +179,7 @@ define void @test11(i1 %c, i8** %ptr.1) {
|
||||||
; CHECK-NEXT: tail call void @fn2_test11() #0
|
; CHECK-NEXT: tail call void @fn2_test11() #0
|
||||||
; CHECK-NEXT: br label [[EXIT]]
|
; CHECK-NEXT: br label [[EXIT]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: store i8* null, i8** [[PTR_1:%.*]], align 8
|
; CHECK-NEXT: store ptr null, ptr [[PTR_1:%.*]], align 8
|
||||||
; CHECK-NEXT: tail call void @fn2_test11() #0
|
; CHECK-NEXT: tail call void @fn2_test11() #0
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
|
@ -192,7 +191,7 @@ if.then: ; preds = %entry
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
store i8* null, i8** %ptr.1, align 8
|
store ptr null, ptr %ptr.1, align 8
|
||||||
tail call void @fn2_test11() #1
|
tail call void @fn2_test11() #1
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,80 +5,80 @@ target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||||
|
|
||||||
declare void @readnone_may_throw() readnone
|
declare void @readnone_may_throw() readnone
|
||||||
|
|
||||||
declare void @use(i32 *)
|
declare void @use(ptr)
|
||||||
|
|
||||||
; Tests where the pointer/object is accessible after the function returns.
|
; Tests where the pointer/object is accessible after the function returns.
|
||||||
|
|
||||||
; Cannot remove the store from the entry block, because the call in bb2 may throw.
|
; Cannot remove the store from the entry block, because the call in bb2 may throw.
|
||||||
define void @accessible_after_return_1(i32* noalias %P, i1 %c1) {
|
define void @accessible_after_return_1(ptr noalias %P, i1 %c1) {
|
||||||
; CHECK-LABEL: @accessible_after_return_1(
|
; CHECK-LABEL: @accessible_after_return_1(
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5:%.*]]
|
; CHECK-NEXT: br label [[BB5:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: call void @readnone_may_throw()
|
; CHECK-NEXT: call void @readnone_may_throw()
|
||||||
; CHECK-NEXT: store i32 3, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 3, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
; CHECK: bb5:
|
; CHECK: bb5:
|
||||||
; CHECK-NEXT: call void @use(i32* [[P]])
|
; CHECK-NEXT: call void @use(ptr [[P]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 %c1, label %bb1, label %bb2
|
br i1 %c1, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
call void @readnone_may_throw()
|
call void @readnone_may_throw()
|
||||||
store i32 3, i32* %P
|
store i32 3, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb5:
|
bb5:
|
||||||
call void @use(i32* %P)
|
call void @use(ptr %P)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Cannot remove the store from the entry block, because the call in bb3 may throw.
|
; Cannot remove the store from the entry block, because the call in bb3 may throw.
|
||||||
define void @accessible_after_return6(i32* %P, i1 %c.1, i1 %c.2) {
|
define void @accessible_after_return6(ptr %P, i1 %c.1, i1 %c.2) {
|
||||||
; CHECK-LABEL: @accessible_after_return6(
|
; CHECK-LABEL: @accessible_after_return6(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
|
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: call void @readnone_may_throw()
|
; CHECK-NEXT: call void @readnone_may_throw()
|
||||||
; CHECK-NEXT: store i32 2, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 2, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb4:
|
; CHECK: bb4:
|
||||||
; CHECK-NEXT: store i32 3, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 3, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 %c.1, label %bb1, label %bb2
|
br i1 %c.1, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
br i1 %c.2, label %bb3, label %bb4
|
br i1 %c.2, label %bb3, label %bb4
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
call void @readnone_may_throw()
|
call void @readnone_may_throw()
|
||||||
store i32 2, i32* %P
|
store i32 2, ptr %P
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
bb4:
|
bb4:
|
||||||
store i32 3, i32* %P
|
store i32 3, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,32 +93,32 @@ define void @alloca_1(i1 %c1) {
|
||||||
; CHECK-NEXT: [[P:%.*]] = alloca i32
|
; CHECK-NEXT: [[P:%.*]] = alloca i32
|
||||||
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5:%.*]]
|
; CHECK-NEXT: br label [[BB5:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: call void @readnone_may_throw()
|
; CHECK-NEXT: call void @readnone_may_throw()
|
||||||
; CHECK-NEXT: store i32 3, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 3, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
; CHECK: bb5:
|
; CHECK: bb5:
|
||||||
; CHECK-NEXT: call void @use(i32* [[P]])
|
; CHECK-NEXT: call void @use(ptr [[P]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%P = alloca i32
|
%P = alloca i32
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 %c1, label %bb1, label %bb2
|
br i1 %c1, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
call void @readnone_may_throw()
|
call void @readnone_may_throw()
|
||||||
store i32 3, i32* %P
|
store i32 3, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb5:
|
bb5:
|
||||||
call void @use(i32* %P)
|
call void @use(ptr %P)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,27 +130,27 @@ define void @alloca_2(i1 %c.1, i1 %c.2) {
|
||||||
; CHECK-NEXT: [[P:%.*]] = alloca i32
|
; CHECK-NEXT: [[P:%.*]] = alloca i32
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5:%.*]]
|
; CHECK-NEXT: br label [[BB5:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
|
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: call void @readnone_may_throw()
|
; CHECK-NEXT: call void @readnone_may_throw()
|
||||||
; CHECK-NEXT: store i32 3, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 3, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
; CHECK: bb4:
|
; CHECK: bb4:
|
||||||
; CHECK-NEXT: store i32 5, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 5, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
; CHECK: bb5:
|
; CHECK: bb5:
|
||||||
; CHECK-NEXT: call void @use(i32* [[P]])
|
; CHECK-NEXT: call void @use(ptr [[P]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%P = alloca i32
|
%P = alloca i32
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 %c.1, label %bb1, label %bb2
|
br i1 %c.1, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
|
@ -158,14 +158,14 @@ bb2:
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
call void @readnone_may_throw()
|
call void @readnone_may_throw()
|
||||||
store i32 3, i32* %P
|
store i32 3, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb4:
|
bb4:
|
||||||
store i32 5, i32* %P
|
store i32 5, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb5:
|
bb5:
|
||||||
call void @use(i32* %P)
|
call void @use(ptr %P)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,129 +3,129 @@
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||||
|
|
||||||
declare void @use(i32 *)
|
declare void @use(ptr)
|
||||||
|
|
||||||
; Tests where the pointer/object is accessible after the function returns.
|
; Tests where the pointer/object is accessible after the function returns.
|
||||||
|
|
||||||
define void @accessible_after_return_1(i32* noalias %P, i1 %c1) {
|
define void @accessible_after_return_1(ptr noalias %P, i1 %c1) {
|
||||||
; CHECK-LABEL: @accessible_after_return_1(
|
; CHECK-LABEL: @accessible_after_return_1(
|
||||||
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5:%.*]]
|
; CHECK-NEXT: br label [[BB5:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: store i32 3, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 3, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
; CHECK: bb5:
|
; CHECK: bb5:
|
||||||
; CHECK-NEXT: call void @use(i32* [[P]])
|
; CHECK-NEXT: call void @use(ptr [[P]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 %c1, label %bb1, label %bb2
|
br i1 %c1, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
bb2:
|
bb2:
|
||||||
store i32 3, i32* %P
|
store i32 3, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb5:
|
bb5:
|
||||||
call void @use(i32* %P)
|
call void @use(ptr %P)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @accessible_after_return_2(i32* noalias %P, i1 %c.1, i1 %c.2) {
|
define void @accessible_after_return_2(ptr noalias %P, i1 %c.1, i1 %c.2) {
|
||||||
; CHECK-LABEL: @accessible_after_return_2(
|
; CHECK-LABEL: @accessible_after_return_2(
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5:%.*]]
|
; CHECK-NEXT: br label [[BB5:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
|
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 3, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 3, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
; CHECK: bb4:
|
; CHECK: bb4:
|
||||||
; CHECK-NEXT: store i32 5, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 5, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
; CHECK: bb5:
|
; CHECK: bb5:
|
||||||
; CHECK-NEXT: call void @use(i32* [[P]])
|
; CHECK-NEXT: call void @use(ptr [[P]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 %c.1, label %bb1, label %bb2
|
br i1 %c.1, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
br i1 %c.2, label %bb3, label %bb4
|
br i1 %c.2, label %bb3, label %bb4
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
store i32 3, i32* %P
|
store i32 3, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb4:
|
bb4:
|
||||||
store i32 5, i32* %P
|
store i32 5, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb5:
|
bb5:
|
||||||
call void @use(i32* %P)
|
call void @use(ptr %P)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Cannot remove store in entry block because it is not overwritten on path
|
; Cannot remove store in entry block because it is not overwritten on path
|
||||||
; entry->bb2->bb5.
|
; entry->bb2->bb5.
|
||||||
define void @accessible_after_return_3(i32* noalias %P, i1 %c1) {
|
define void @accessible_after_return_3(ptr noalias %P, i1 %c1) {
|
||||||
; CHECK-LABEL: @accessible_after_return_3(
|
; CHECK-LABEL: @accessible_after_return_3(
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5:%.*]]
|
; CHECK-NEXT: br label [[BB5:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
; CHECK: bb5:
|
; CHECK: bb5:
|
||||||
; CHECK-NEXT: call void @use(i32* [[P]])
|
; CHECK-NEXT: call void @use(ptr [[P]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 %c1, label %bb1, label %bb2
|
br i1 %c1, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb5:
|
bb5:
|
||||||
call void @use(i32* %P)
|
call void @use(ptr %P)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Cannot remove store in entry block because it is not overwritten on path
|
; Cannot remove store in entry block because it is not overwritten on path
|
||||||
; entry->bb2->bb5.
|
; entry->bb2->bb5.
|
||||||
define void @accessible_after_return_4(i32* noalias %P, i1 %c1) {
|
define void @accessible_after_return_4(ptr noalias %P, i1 %c1) {
|
||||||
; CHECK-LABEL: @accessible_after_return_4(
|
; CHECK-LABEL: @accessible_after_return_4(
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: call void @use(i32* [[P]])
|
; CHECK-NEXT: call void @use(ptr [[P]])
|
||||||
; CHECK-NEXT: br label [[BB5:%.*]]
|
; CHECK-NEXT: br label [[BB5:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
; CHECK: bb5:
|
; CHECK: bb5:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 %c1, label %bb1, label %bb2
|
br i1 %c1, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
call void @use(i32* %P)
|
call void @use(ptr %P)
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
|
@ -137,18 +137,18 @@ bb5:
|
||||||
|
|
||||||
; Cannot remove the store in entry, as it is not overwritten on all paths to an
|
; Cannot remove the store in entry, as it is not overwritten on all paths to an
|
||||||
; exit (patch including bb4).
|
; exit (patch including bb4).
|
||||||
define void @accessible_after_return5(i32* %P, i1 %c.1, i1 %c.2) {
|
define void @accessible_after_return5(ptr %P, i1 %c.1, i1 %c.2) {
|
||||||
; CHECK-LABEL: @accessible_after_return5(
|
; CHECK-LABEL: @accessible_after_return5(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
|
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5:%.*]]
|
; CHECK-NEXT: br label [[BB5:%.*]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 2, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 2, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
; CHECK: bb4:
|
; CHECK: bb4:
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
|
@ -156,18 +156,18 @@ define void @accessible_after_return5(i32* %P, i1 %c.1, i1 %c.2) {
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 %c.1, label %bb1, label %bb2
|
br i1 %c.1, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
br i1 %c.2, label %bb3, label %bb4
|
br i1 %c.2, label %bb3, label %bb4
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
store i32 2, i32* %P
|
store i32 2, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb4:
|
bb4:
|
||||||
|
@ -178,55 +178,55 @@ bb5:
|
||||||
}
|
}
|
||||||
|
|
||||||
; Can remove store in entry block, because it is overwritten before each return.
|
; Can remove store in entry block, because it is overwritten before each return.
|
||||||
define void @accessible_after_return6(i32* %P, i1 %c.1, i1 %c.2) {
|
define void @accessible_after_return6(ptr %P, i1 %c.1, i1 %c.2) {
|
||||||
; CHECK-LABEL: @accessible_after_return6(
|
; CHECK-LABEL: @accessible_after_return6(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
|
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 2, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 2, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb4:
|
; CHECK: bb4:
|
||||||
; CHECK-NEXT: store i32 3, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 3, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 %c.1, label %bb1, label %bb2
|
br i1 %c.1, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
br i1 %c.2, label %bb3, label %bb4
|
br i1 %c.2, label %bb3, label %bb4
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
store i32 2, i32* %P
|
store i32 2, ptr %P
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
bb4:
|
bb4:
|
||||||
store i32 3, i32* %P
|
store i32 3, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Can remove store in bb1, because it is overwritten along each path
|
; Can remove store in bb1, because it is overwritten along each path
|
||||||
; from bb1 to the exit.
|
; from bb1 to the exit.
|
||||||
define void @accessible_after_return7(i32* %P, i1 %c.1, i1 %c.2) {
|
define void @accessible_after_return7(ptr %P, i1 %c.1, i1 %c.2) {
|
||||||
; CHECK-LABEL: @accessible_after_return7(
|
; CHECK-LABEL: @accessible_after_return7(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
|
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 2, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 2, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5:%.*]]
|
; CHECK-NEXT: br label [[BB5:%.*]]
|
||||||
; CHECK: bb4:
|
; CHECK: bb4:
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
|
@ -237,15 +237,15 @@ entry:
|
||||||
br i1 %c.1, label %bb1, label %bb2
|
br i1 %c.1, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 %c.2, label %bb3, label %bb4
|
br i1 %c.2, label %bb3, label %bb4
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
store i32 2, i32* %P
|
store i32 2, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb4:
|
bb4:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
|
@ -258,18 +258,18 @@ bb5:
|
||||||
|
|
||||||
; Cannot remove store in entry block, because it is overwritten along each path to
|
; Cannot remove store in entry block, because it is overwritten along each path to
|
||||||
; the exit (entry->bb1->bb4->bb5).
|
; the exit (entry->bb1->bb4->bb5).
|
||||||
define void @accessible_after_return8(i32* %P, i1 %c.1, i1 %c.2) {
|
define void @accessible_after_return8(ptr %P, i1 %c.1, i1 %c.2) {
|
||||||
; CHECK-LABEL: @accessible_after_return8(
|
; CHECK-LABEL: @accessible_after_return8(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
|
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5:%.*]]
|
; CHECK-NEXT: br label [[BB5:%.*]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 2, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 2, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
; CHECK: bb4:
|
; CHECK: bb4:
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
|
@ -277,18 +277,18 @@ define void @accessible_after_return8(i32* %P, i1 %c.1, i1 %c.2) {
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 %c.1, label %bb1, label %bb2
|
br i1 %c.1, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
br i1 %c.2, label %bb3, label %bb4
|
br i1 %c.2, label %bb3, label %bb4
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
store i32 2, i32* %P
|
store i32 2, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb4:
|
bb4:
|
||||||
|
@ -300,23 +300,23 @@ bb5:
|
||||||
|
|
||||||
; Make sure no stores are removed here. In particular, the store in if.then
|
; Make sure no stores are removed here. In particular, the store in if.then
|
||||||
; should not be removed.
|
; should not be removed.
|
||||||
define void @accessible_after_return9(i8* noalias %ptr) {
|
define void @accessible_after_return9(ptr noalias %ptr) {
|
||||||
; CHECK-LABEL: @accessible_after_return9(
|
; CHECK-LABEL: @accessible_after_return9(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond()
|
; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond()
|
||||||
; CHECK-NEXT: br i1 [[C_0]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
; CHECK-NEXT: br i1 [[C_0]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
||||||
; CHECK: for.body:
|
; CHECK: for.body:
|
||||||
; CHECK-NEXT: store i8 99, i8* [[PTR:%.*]], align 8
|
; CHECK-NEXT: store i8 99, ptr [[PTR:%.*]], align 8
|
||||||
; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
|
; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
|
||||||
; CHECK-NEXT: br i1 [[C_1]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
; CHECK-NEXT: br i1 [[C_1]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
||||||
; CHECK: if.then:
|
; CHECK: if.then:
|
||||||
; CHECK-NEXT: store i8 20, i8* [[PTR]], align 8
|
; CHECK-NEXT: store i8 20, ptr [[PTR]], align 8
|
||||||
; CHECK-NEXT: br label [[IF_END]]
|
; CHECK-NEXT: br label [[IF_END]]
|
||||||
; CHECK: if.end:
|
; CHECK: if.end:
|
||||||
; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()
|
; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()
|
||||||
; CHECK-NEXT: br i1 [[C_2]], label [[IF_THEN10:%.*]], label [[FOR_INC:%.*]]
|
; CHECK-NEXT: br i1 [[C_2]], label [[IF_THEN10:%.*]], label [[FOR_INC:%.*]]
|
||||||
; CHECK: if.then10:
|
; CHECK: if.then10:
|
||||||
; CHECK-NEXT: store i8 0, i8* [[PTR]], align 8
|
; CHECK-NEXT: store i8 0, ptr [[PTR]], align 8
|
||||||
; CHECK-NEXT: br label [[FOR_INC]]
|
; CHECK-NEXT: br label [[FOR_INC]]
|
||||||
; CHECK: for.inc:
|
; CHECK: for.inc:
|
||||||
; CHECK-NEXT: [[C_3:%.*]] = call i1 @cond()
|
; CHECK-NEXT: [[C_3:%.*]] = call i1 @cond()
|
||||||
|
@ -329,12 +329,12 @@ entry:
|
||||||
br i1 %c.0, label %for.body, label %for.end
|
br i1 %c.0, label %for.body, label %for.end
|
||||||
|
|
||||||
for.body:
|
for.body:
|
||||||
store i8 99, i8* %ptr, align 8
|
store i8 99, ptr %ptr, align 8
|
||||||
%c.1 = call i1 @cond()
|
%c.1 = call i1 @cond()
|
||||||
br i1 %c.1, label %if.end, label %if.then
|
br i1 %c.1, label %if.end, label %if.then
|
||||||
|
|
||||||
if.then:
|
if.then:
|
||||||
store i8 20, i8* %ptr, align 8
|
store i8 20, ptr %ptr, align 8
|
||||||
br label %if.end
|
br label %if.end
|
||||||
|
|
||||||
if.end:
|
if.end:
|
||||||
|
@ -342,7 +342,7 @@ if.end:
|
||||||
br i1 %c.2, label %if.then10, label %for.inc
|
br i1 %c.2, label %if.then10, label %for.inc
|
||||||
|
|
||||||
if.then10:
|
if.then10:
|
||||||
store i8 0, i8* %ptr, align 8
|
store i8 0, ptr %ptr, align 8
|
||||||
br label %for.inc
|
br label %for.inc
|
||||||
|
|
||||||
for.inc:
|
for.inc:
|
||||||
|
@ -356,18 +356,18 @@ for.end:
|
||||||
; Cannot remove store in entry block because it is not overwritten on path
|
; Cannot remove store in entry block because it is not overwritten on path
|
||||||
; entry->bb2->bb4. Also make sure we deal with dead exit blocks without
|
; entry->bb2->bb4. Also make sure we deal with dead exit blocks without
|
||||||
; crashing.
|
; crashing.
|
||||||
define void @accessible_after_return10_dead_block(i32* %P, i1 %c.1, i1 %c.2) {
|
define void @accessible_after_return10_dead_block(ptr %P, i1 %c.1, i1 %c.2) {
|
||||||
; CHECK-LABEL: @accessible_after_return10_dead_block(
|
; CHECK-LABEL: @accessible_after_return10_dead_block(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
|
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 2, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 2, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb4:
|
; CHECK: bb4:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
|
@ -375,18 +375,18 @@ define void @accessible_after_return10_dead_block(i32* %P, i1 %c.1, i1 %c.2) {
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 %c.1, label %bb1, label %bb2
|
br i1 %c.1, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
br i1 %c.2, label %bb3, label %bb4
|
br i1 %c.2, label %bb3, label %bb4
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
store i32 2, i32* %P
|
store i32 2, ptr %P
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
bb4:
|
bb4:
|
||||||
|
@ -406,8 +406,8 @@ define void @accessible_after_return11_loop() {
|
||||||
; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
|
; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
|
||||||
; CHECK-NEXT: br i1 [[C_1]], label [[FOR_BODY_I]], label [[INIT_PARSE_EXIT:%.*]]
|
; CHECK-NEXT: br i1 [[C_1]], label [[FOR_BODY_I]], label [[INIT_PARSE_EXIT:%.*]]
|
||||||
; CHECK: init_parse.exit:
|
; CHECK: init_parse.exit:
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull undef)
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull undef)
|
||||||
; CHECK-NEXT: store i32 0, i32* @linenum, align 4
|
; CHECK-NEXT: store i32 0, ptr @linenum, align 4
|
||||||
; CHECK-NEXT: br label [[FOR_BODY_I20:%.*]]
|
; CHECK-NEXT: br label [[FOR_BODY_I20:%.*]]
|
||||||
; CHECK: for.body.i20:
|
; CHECK: for.body.i20:
|
||||||
; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()
|
; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()
|
||||||
|
@ -423,9 +423,9 @@ for.body.i: ; preds = %for.body.i, %entry
|
||||||
br i1 %c.1, label %for.body.i, label %init_parse.exit
|
br i1 %c.1, label %for.body.i, label %init_parse.exit
|
||||||
|
|
||||||
init_parse.exit: ; preds = %for.body.i
|
init_parse.exit: ; preds = %for.body.i
|
||||||
store i32 0, i32* @linenum, align 4
|
store i32 0, ptr @linenum, align 4
|
||||||
call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull undef) #2
|
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull undef) #2
|
||||||
store i32 0, i32* @linenum, align 4
|
store i32 0, ptr @linenum, align 4
|
||||||
br label %for.body.i20
|
br label %for.body.i20
|
||||||
|
|
||||||
for.body.i20: ; preds = %for.body.i20, %init_parse.exit
|
for.body.i20: ; preds = %for.body.i20, %init_parse.exit
|
||||||
|
@ -435,7 +435,7 @@ for.body.i20: ; preds = %for.body.i20, %init
|
||||||
exit:
|
exit:
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
|
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
|
||||||
declare i1 @cond() readnone nounwind
|
declare i1 @cond() readnone nounwind
|
||||||
|
|
||||||
; Tests where the pointer/object is *NOT* accessible after the function returns.
|
; Tests where the pointer/object is *NOT* accessible after the function returns.
|
||||||
|
@ -447,28 +447,28 @@ define void @alloca_1(i1 %c1) {
|
||||||
; CHECK-NEXT: [[P:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[P:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5:%.*]]
|
; CHECK-NEXT: br label [[BB5:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: store i32 3, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 3, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
; CHECK: bb5:
|
; CHECK: bb5:
|
||||||
; CHECK-NEXT: call void @use(i32* [[P]])
|
; CHECK-NEXT: call void @use(ptr [[P]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%P = alloca i32
|
%P = alloca i32
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 %c1, label %bb1, label %bb2
|
br i1 %c1, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
bb2:
|
bb2:
|
||||||
store i32 3, i32* %P
|
store i32 3, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb5:
|
bb5:
|
||||||
call void @use(i32* %P)
|
call void @use(ptr %P)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,41 +479,41 @@ define void @alloca_2(i1 %c.1, i1 %c.2) {
|
||||||
; CHECK-NEXT: [[P:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[P:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5:%.*]]
|
; CHECK-NEXT: br label [[BB5:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
|
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 3, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 3, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
; CHECK: bb4:
|
; CHECK: bb4:
|
||||||
; CHECK-NEXT: store i32 5, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 5, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
; CHECK: bb5:
|
; CHECK: bb5:
|
||||||
; CHECK-NEXT: call void @use(i32* [[P]])
|
; CHECK-NEXT: call void @use(ptr [[P]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%P = alloca i32
|
%P = alloca i32
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 %c.1, label %bb1, label %bb2
|
br i1 %c.1, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
br i1 %c.2, label %bb3, label %bb4
|
br i1 %c.2, label %bb3, label %bb4
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
store i32 3, i32* %P
|
store i32 3, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb4:
|
bb4:
|
||||||
store i32 5, i32* %P
|
store i32 5, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb5:
|
bb5:
|
||||||
call void @use(i32* %P)
|
call void @use(ptr %P)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,29 +522,29 @@ bb5:
|
||||||
define void @alloca_3(i1 %c1) {
|
define void @alloca_3(i1 %c1) {
|
||||||
; CHECK-LABEL: @alloca_3(
|
; CHECK-LABEL: @alloca_3(
|
||||||
; CHECK-NEXT: [[P:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[P:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB5:%.*]]
|
; CHECK-NEXT: br label [[BB5:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
; CHECK: bb5:
|
; CHECK: bb5:
|
||||||
; CHECK-NEXT: call void @use(i32* [[P]])
|
; CHECK-NEXT: call void @use(ptr [[P]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%P = alloca i32
|
%P = alloca i32
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 %c1, label %bb1, label %bb2
|
br i1 %c1, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br label %bb5
|
br label %bb5
|
||||||
bb2:
|
bb2:
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb5:
|
bb5:
|
||||||
call void @use(i32* %P)
|
call void @use(ptr %P)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,8 +556,8 @@ define void @alloca_4(i1 %c1) {
|
||||||
; CHECK-NEXT: [[P:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[P:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: call void @use(i32* [[P]])
|
; CHECK-NEXT: call void @use(ptr [[P]])
|
||||||
; CHECK-NEXT: br label [[BB5:%.*]]
|
; CHECK-NEXT: br label [[BB5:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: br label [[BB5]]
|
; CHECK-NEXT: br label [[BB5]]
|
||||||
|
@ -565,12 +565,12 @@ define void @alloca_4(i1 %c1) {
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%P = alloca i32
|
%P = alloca i32
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 %c1, label %bb1, label %bb2
|
br i1 %c1, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
call void @use(i32* %P)
|
call void @use(ptr %P)
|
||||||
br label %bb5
|
br label %bb5
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
|
@ -581,60 +581,57 @@ bb5:
|
||||||
}
|
}
|
||||||
|
|
||||||
%struct.blam.4 = type { %struct.bar.5, [4 x i8] }
|
%struct.blam.4 = type { %struct.bar.5, [4 x i8] }
|
||||||
%struct.bar.5 = type <{ i64, i64*, i32, i64 }>
|
%struct.bar.5 = type <{ i64, ptr, i32, i64 }>
|
||||||
|
|
||||||
; Make sure we do not eliminate the store in %bb.
|
; Make sure we do not eliminate the store in %bb.
|
||||||
define void @alloca_5(i1 %c) {
|
define void @alloca_5(i1 %c) {
|
||||||
; CHECK-LABEL: @alloca_5(
|
; CHECK-LABEL: @alloca_5(
|
||||||
; CHECK-NEXT: bb:
|
; CHECK-NEXT: bb:
|
||||||
; CHECK-NEXT: [[TMP:%.*]] = alloca [[STRUCT_BLAM_4:%.*]], align 8
|
; CHECK-NEXT: [[TMP:%.*]] = alloca [[STRUCT_BLAM_4:%.*]], align 8
|
||||||
; CHECK-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_BLAM_4]], %struct.blam.4* [[TMP]], i64 0, i32 0, i32 3
|
; CHECK-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_BLAM_4]], ptr [[TMP]], i64 0, i32 0, i32 3
|
||||||
; CHECK-NEXT: [[TMP39:%.*]] = bitcast i64* [[TMP38]] to i64*
|
; CHECK-NEXT: store i64 0, ptr [[TMP38]], align 4
|
||||||
; CHECK-NEXT: store i64 0, i64* [[TMP39]], align 4
|
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB46:%.*]], label [[BB47:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB46:%.*]], label [[BB47:%.*]]
|
||||||
; CHECK: bb46:
|
; CHECK: bb46:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb47:
|
; CHECK: bb47:
|
||||||
; CHECK-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT_BLAM_4]], %struct.blam.4* [[TMP]], i64 0, i32 0, i32 2
|
; CHECK-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT_BLAM_4]], ptr [[TMP]], i64 0, i32 0, i32 2
|
||||||
; CHECK-NEXT: store i32 20, i32* [[TMP48]], align 8
|
; CHECK-NEXT: store i32 20, ptr [[TMP48]], align 8
|
||||||
; CHECK-NEXT: br label [[BB52:%.*]]
|
; CHECK-NEXT: br label [[BB52:%.*]]
|
||||||
; CHECK: bb52:
|
; CHECK: bb52:
|
||||||
; CHECK-NEXT: br i1 [[C]], label [[BB68:%.*]], label [[BB59:%.*]]
|
; CHECK-NEXT: br i1 [[C]], label [[BB68:%.*]], label [[BB59:%.*]]
|
||||||
; CHECK: bb59:
|
; CHECK: bb59:
|
||||||
; CHECK-NEXT: call void @use.2(%struct.blam.4* [[TMP]])
|
; CHECK-NEXT: call void @use.2(ptr [[TMP]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb68:
|
; CHECK: bb68:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
bb:
|
bb:
|
||||||
%tmp = alloca %struct.blam.4, align 8
|
%tmp = alloca %struct.blam.4, align 8
|
||||||
%tmp36 = getelementptr inbounds %struct.blam.4, %struct.blam.4* %tmp, i64 0, i32 0, i32 1
|
%tmp36 = getelementptr inbounds %struct.blam.4, ptr %tmp, i64 0, i32 0, i32 1
|
||||||
%tmp37 = bitcast i64** %tmp36 to i8*
|
%tmp38 = getelementptr inbounds %struct.blam.4, ptr %tmp, i64 0, i32 0, i32 3
|
||||||
%tmp38 = getelementptr inbounds %struct.blam.4, %struct.blam.4* %tmp, i64 0, i32 0, i32 3
|
store i64 0, ptr %tmp38, align 4
|
||||||
%tmp39 = bitcast i64* %tmp38 to i64*
|
|
||||||
store i64 0, i64* %tmp39, align 4
|
|
||||||
br i1 %c, label %bb46, label %bb47
|
br i1 %c, label %bb46, label %bb47
|
||||||
|
|
||||||
bb46: ; preds = %bb12
|
bb46: ; preds = %bb12
|
||||||
call void @llvm.memset.p0i8.i64(i8* nonnull align 8 dereferenceable(20) %tmp37, i8 0, i64 26, i1 false)
|
call void @llvm.memset.p0.i64(ptr nonnull align 8 dereferenceable(20) %tmp36, i8 0, i64 26, i1 false)
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
bb47: ; preds = %bb12
|
bb47: ; preds = %bb12
|
||||||
%tmp48 = getelementptr inbounds %struct.blam.4, %struct.blam.4* %tmp, i64 0, i32 0, i32 2
|
%tmp48 = getelementptr inbounds %struct.blam.4, ptr %tmp, i64 0, i32 0, i32 2
|
||||||
store i32 20, i32* %tmp48, align 8
|
store i32 20, ptr %tmp48, align 8
|
||||||
br label %bb52
|
br label %bb52
|
||||||
|
|
||||||
bb52: ; preds = %bb47
|
bb52: ; preds = %bb47
|
||||||
br i1 %c, label %bb68, label %bb59
|
br i1 %c, label %bb68, label %bb59
|
||||||
|
|
||||||
bb59: ; preds = %bb52
|
bb59: ; preds = %bb52
|
||||||
call void @use.2(%struct.blam.4* %tmp)
|
call void @use.2(ptr %tmp)
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
bb68: ; preds = %bb52
|
bb68: ; preds = %bb52
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @use.2(%struct.blam.4*)
|
declare void @use.2(ptr)
|
||||||
|
|
||||||
declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg)
|
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg)
|
||||||
|
|
|
@ -5,42 +5,39 @@
|
||||||
%struct.ham = type { [3 x double], [3 x double]}
|
%struct.ham = type { [3 x double], [3 x double]}
|
||||||
|
|
||||||
declare void @may_throw()
|
declare void @may_throw()
|
||||||
declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg)
|
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg)
|
||||||
|
|
||||||
; We miss this case, because of an aggressive limit of partial overlap analysis.
|
; We miss this case, because of an aggressive limit of partial overlap analysis.
|
||||||
; With a larger partial store limit, we remove the memset.
|
; With a larger partial store limit, we remove the memset.
|
||||||
define void @overlap1(%struct.ham* %arg, i1 %cond) {
|
define void @overlap1(ptr %arg, i1 %cond) {
|
||||||
; CHECK-LABEL: @overlap1(
|
; CHECK-LABEL: @overlap1(
|
||||||
; CHECK-NEXT: bb:
|
; CHECK-NEXT: bb:
|
||||||
; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds [[STRUCT_HAM:%.*]], %struct.ham* [[ARG:%.*]], i64 0, i32 0, i64 2
|
; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds [[STRUCT_HAM:%.*]], ptr [[ARG:%.*]], i64 0, i32 0, i64 2
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 0, i64 1
|
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_HAM]], ptr [[ARG]], i64 0, i32 0, i64 1
|
||||||
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 0, i64 0
|
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[STRUCT_HAM]], ptr [[ARG]], i64 0, i32 1, i64 2
|
||||||
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 1, i64 2
|
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_HAM]], ptr [[ARG]], i64 0, i32 1, i64 1
|
||||||
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 1, i64 1
|
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_HAM]], ptr [[ARG]], i64 0, i32 1, i32 0
|
||||||
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 1, i32 0
|
|
||||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB7:%.*]], label [[BB8:%.*]]
|
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB7:%.*]], label [[BB8:%.*]]
|
||||||
; CHECK: bb7:
|
; CHECK: bb7:
|
||||||
; CHECK-NEXT: br label [[BB9:%.*]]
|
; CHECK-NEXT: br label [[BB9:%.*]]
|
||||||
; CHECK: bb8:
|
; CHECK: bb8:
|
||||||
; CHECK-NEXT: br label [[BB9]]
|
; CHECK-NEXT: br label [[BB9]]
|
||||||
; CHECK: bb9:
|
; CHECK: bb9:
|
||||||
; CHECK-NEXT: store double 1.000000e+00, double* [[TMP2]], align 8
|
; CHECK-NEXT: store double 1.000000e+00, ptr [[ARG]], align 8
|
||||||
; CHECK-NEXT: store double 2.000000e+00, double* [[TMP1]], align 8
|
; CHECK-NEXT: store double 2.000000e+00, ptr [[TMP1]], align 8
|
||||||
; CHECK-NEXT: store double 3.000000e+00, double* [[TMP]], align 8
|
; CHECK-NEXT: store double 3.000000e+00, ptr [[TMP]], align 8
|
||||||
; CHECK-NEXT: store double 4.000000e+00, double* [[TMP5]], align 8
|
; CHECK-NEXT: store double 4.000000e+00, ptr [[TMP5]], align 8
|
||||||
; CHECK-NEXT: store double 5.000000e+00, double* [[TMP4]], align 8
|
; CHECK-NEXT: store double 5.000000e+00, ptr [[TMP4]], align 8
|
||||||
; CHECK-NEXT: store double 6.000000e+00, double* [[TMP3]], align 8
|
; CHECK-NEXT: store double 6.000000e+00, ptr [[TMP3]], align 8
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
bb:
|
bb:
|
||||||
%tmp = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 0, i64 2
|
%tmp = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 0, i64 2
|
||||||
%tmp1 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 0, i64 1
|
%tmp1 = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 0, i64 1
|
||||||
%tmp2 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 0, i64 0
|
%tmp3 = getelementptr inbounds %struct.ham, ptr %arg, i64 0,i32 1, i64 2
|
||||||
%tmp3 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0,i32 1, i64 2
|
%tmp4 = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 1, i64 1
|
||||||
%tmp4 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 1, i64 1
|
%tmp5 = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 1, i32 0
|
||||||
%tmp5 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 1, i32 0
|
call void @llvm.memset.p0.i64(ptr nonnull align 8 dereferenceable(48) %arg, i8 0, i64 48, i1 false)
|
||||||
%tmp6 = bitcast double* %tmp2 to i8*
|
|
||||||
call void @llvm.memset.p0i8.i64(i8* nonnull align 8 dereferenceable(48) %tmp6, i8 0, i64 48, i1 false)
|
|
||||||
br i1 %cond, label %bb7, label %bb8
|
br i1 %cond, label %bb7, label %bb8
|
||||||
|
|
||||||
bb7: ; preds = %bb
|
bb7: ; preds = %bb
|
||||||
|
@ -50,26 +47,24 @@ bb8: ; preds = %bb
|
||||||
br label %bb9
|
br label %bb9
|
||||||
|
|
||||||
bb9: ; preds = %bb8, %bb7
|
bb9: ; preds = %bb8, %bb7
|
||||||
store double 1.0, double* %tmp2, align 8
|
store double 1.0, ptr %arg, align 8
|
||||||
store double 2.0, double* %tmp1, align 8
|
store double 2.0, ptr %tmp1, align 8
|
||||||
store double 3.0, double* %tmp, align 8
|
store double 3.0, ptr %tmp, align 8
|
||||||
store double 4.0, double* %tmp5, align 8
|
store double 4.0, ptr %tmp5, align 8
|
||||||
store double 5.0, double* %tmp4, align 8
|
store double 5.0, ptr %tmp4, align 8
|
||||||
store double 6.0, double* %tmp3, align 8
|
store double 6.0, ptr %tmp3, align 8
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @overlap2(%struct.ham* %arg, i1 %cond) {
|
define void @overlap2(ptr %arg, i1 %cond) {
|
||||||
; CHECK-LABEL: @overlap2(
|
; CHECK-LABEL: @overlap2(
|
||||||
; CHECK-NEXT: bb:
|
; CHECK-NEXT: bb:
|
||||||
; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds [[STRUCT_HAM:%.*]], %struct.ham* [[ARG:%.*]], i64 0, i32 0, i64 2
|
; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds [[STRUCT_HAM:%.*]], ptr [[ARG:%.*]], i64 0, i32 0, i64 2
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 0, i64 1
|
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_HAM]], ptr [[ARG]], i64 0, i32 0, i64 1
|
||||||
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 0, i64 0
|
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[STRUCT_HAM]], ptr [[ARG]], i64 0, i32 1, i64 2
|
||||||
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 1, i64 2
|
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_HAM]], ptr [[ARG]], i64 0, i32 1, i64 1
|
||||||
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 1, i64 1
|
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_HAM]], ptr [[ARG]], i64 0, i32 1, i32 0
|
||||||
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[STRUCT_HAM]], %struct.ham* [[ARG]], i64 0, i32 1, i32 0
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr nonnull align 8 dereferenceable(48) [[ARG]], i8 0, i64 48, i1 false)
|
||||||
; CHECK-NEXT: [[TMP6:%.*]] = bitcast double* [[TMP2]] to i8*
|
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 8 dereferenceable(48) [[TMP6]], i8 0, i64 48, i1 false)
|
|
||||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB7:%.*]], label [[BB8:%.*]]
|
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB7:%.*]], label [[BB8:%.*]]
|
||||||
; CHECK: bb7:
|
; CHECK: bb7:
|
||||||
; CHECK-NEXT: call void @may_throw()
|
; CHECK-NEXT: call void @may_throw()
|
||||||
|
@ -77,23 +72,21 @@ define void @overlap2(%struct.ham* %arg, i1 %cond) {
|
||||||
; CHECK: bb8:
|
; CHECK: bb8:
|
||||||
; CHECK-NEXT: br label [[BB9]]
|
; CHECK-NEXT: br label [[BB9]]
|
||||||
; CHECK: bb9:
|
; CHECK: bb9:
|
||||||
; CHECK-NEXT: store double 1.000000e+00, double* [[TMP2]], align 8
|
; CHECK-NEXT: store double 1.000000e+00, ptr [[ARG]], align 8
|
||||||
; CHECK-NEXT: store double 2.000000e+00, double* [[TMP1]], align 8
|
; CHECK-NEXT: store double 2.000000e+00, ptr [[TMP1]], align 8
|
||||||
; CHECK-NEXT: store double 3.000000e+00, double* [[TMP]], align 8
|
; CHECK-NEXT: store double 3.000000e+00, ptr [[TMP]], align 8
|
||||||
; CHECK-NEXT: store double 4.000000e+00, double* [[TMP5]], align 8
|
; CHECK-NEXT: store double 4.000000e+00, ptr [[TMP5]], align 8
|
||||||
; CHECK-NEXT: store double 5.000000e+00, double* [[TMP4]], align 8
|
; CHECK-NEXT: store double 5.000000e+00, ptr [[TMP4]], align 8
|
||||||
; CHECK-NEXT: store double 6.000000e+00, double* [[TMP3]], align 8
|
; CHECK-NEXT: store double 6.000000e+00, ptr [[TMP3]], align 8
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
bb:
|
bb:
|
||||||
%tmp = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 0, i64 2
|
%tmp = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 0, i64 2
|
||||||
%tmp1 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 0, i64 1
|
%tmp1 = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 0, i64 1
|
||||||
%tmp2 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 0, i64 0
|
%tmp3 = getelementptr inbounds %struct.ham, ptr %arg, i64 0,i32 1, i64 2
|
||||||
%tmp3 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0,i32 1, i64 2
|
%tmp4 = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 1, i64 1
|
||||||
%tmp4 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 1, i64 1
|
%tmp5 = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 1, i32 0
|
||||||
%tmp5 = getelementptr inbounds %struct.ham, %struct.ham* %arg, i64 0, i32 1, i32 0
|
call void @llvm.memset.p0.i64(ptr nonnull align 8 dereferenceable(48) %arg, i8 0, i64 48, i1 false)
|
||||||
%tmp6 = bitcast double* %tmp2 to i8*
|
|
||||||
call void @llvm.memset.p0i8.i64(i8* nonnull align 8 dereferenceable(48) %tmp6, i8 0, i64 48, i1 false)
|
|
||||||
br i1 %cond, label %bb7, label %bb8
|
br i1 %cond, label %bb7, label %bb8
|
||||||
|
|
||||||
bb7: ; preds = %bb
|
bb7: ; preds = %bb
|
||||||
|
@ -104,41 +97,37 @@ bb8: ; preds = %bb
|
||||||
br label %bb9
|
br label %bb9
|
||||||
|
|
||||||
bb9: ; preds = %bb8, %bb7
|
bb9: ; preds = %bb8, %bb7
|
||||||
store double 1.0, double* %tmp2, align 8
|
store double 1.0, ptr %arg, align 8
|
||||||
store double 2.0, double* %tmp1, align 8
|
store double 2.0, ptr %tmp1, align 8
|
||||||
store double 3.0, double* %tmp, align 8
|
store double 3.0, ptr %tmp, align 8
|
||||||
store double 4.0, double* %tmp5, align 8
|
store double 4.0, ptr %tmp5, align 8
|
||||||
store double 5.0, double* %tmp4, align 8
|
store double 5.0, ptr %tmp4, align 8
|
||||||
store double 6.0, double* %tmp3, align 8
|
store double 6.0, ptr %tmp3, align 8
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Test case from PR46513. Make sure we do not crash.
|
; Test case from PR46513. Make sure we do not crash.
|
||||||
; TODO: we should be able to shorten store i32 844283136, i32* %cast.i32 to a
|
; TODO: we should be able to shorten store i32 844283136, ptr %cast.i32 to a
|
||||||
; store of i16.
|
; store of i16.
|
||||||
define void @overlap_no_dominance([4 x i8]* %arg, i1 %c) {
|
define void @overlap_no_dominance(ptr %arg, i1 %c) {
|
||||||
; CHECK-LABEL: @overlap_no_dominance(
|
; CHECK-LABEL: @overlap_no_dominance(
|
||||||
; CHECK-NEXT: bb:
|
; CHECK-NEXT: bb:
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB13:%.*]], label [[BB9:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB13:%.*]], label [[BB9:%.*]]
|
||||||
; CHECK: bb9:
|
; CHECK: bb9:
|
||||||
; CHECK-NEXT: [[CAST_I32:%.*]] = bitcast [4 x i8]* [[ARG:%.*]] to i32*
|
; CHECK-NEXT: store i32 844283136, ptr [[ARG:%.*]], align 4
|
||||||
; CHECK-NEXT: store i32 844283136, i32* [[CAST_I32]], align 4
|
|
||||||
; CHECK-NEXT: br label [[BB13]]
|
; CHECK-NEXT: br label [[BB13]]
|
||||||
; CHECK: bb13:
|
; CHECK: bb13:
|
||||||
; CHECK-NEXT: [[CAST_I16:%.*]] = bitcast [4 x i8]* [[ARG]] to i16*
|
; CHECK-NEXT: store i16 0, ptr [[ARG]], align 4
|
||||||
; CHECK-NEXT: store i16 0, i16* [[CAST_I16]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
bb:
|
bb:
|
||||||
br i1 %c, label %bb13, label %bb9
|
br i1 %c, label %bb13, label %bb9
|
||||||
|
|
||||||
bb9: ; preds = %bb
|
bb9: ; preds = %bb
|
||||||
%cast.i32 = bitcast [4 x i8]* %arg to i32*
|
store i32 844283136, ptr %arg, align 4
|
||||||
store i32 844283136, i32* %cast.i32, align 4
|
|
||||||
br label %bb13
|
br label %bb13
|
||||||
|
|
||||||
bb13: ; preds = %bb9, %bb
|
bb13: ; preds = %bb9, %bb
|
||||||
%cast.i16 = bitcast [4 x i8]* %arg to i16*
|
store i16 0, ptr %arg, align 4
|
||||||
store i16 0, i16* %cast.i16, align 4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||||
|
|
||||||
define void @second_store_smaller_1(i32* noalias %P, i1 %c) {
|
define void @second_store_smaller_1(ptr noalias %P, i1 %c) {
|
||||||
; CHECK-LABEL: @second_store_smaller_1(
|
; CHECK-LABEL: @second_store_smaller_1(
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
|
@ -14,21 +14,20 @@ define void @second_store_smaller_1(i32* noalias %P, i1 %c) {
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 %c, label %bb1, label %bb2
|
br i1 %c, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
%P.i16 = bitcast i32* %P to i16*
|
store i16 0, ptr %P
|
||||||
store i16 0, i16* %P.i16
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @second_store_smaller_2(i32* noalias %P, i1 %c) {
|
define void @second_store_smaller_2(ptr noalias %P, i1 %c) {
|
||||||
; CHECK-LABEL: @second_store_smaller_2(
|
; CHECK-LABEL: @second_store_smaller_2(
|
||||||
; CHECK-NEXT: store i32 12345, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 12345, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
|
@ -37,109 +36,100 @@ define void @second_store_smaller_2(i32* noalias %P, i1 %c) {
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 %c, label %bb1, label %bb2
|
br i1 %c, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
%P.i16 = bitcast i32* %P to i16*
|
store i16 12345, ptr %P
|
||||||
store i16 12345, i16* %P.i16
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @use(i16) readnone
|
declare void @use(i16) readnone
|
||||||
declare void @use.i8(i8) readnone
|
declare void @use.i8(i8) readnone
|
||||||
|
|
||||||
define void @second_store_smaller_3(i32* noalias %P, i1 %c) {
|
define void @second_store_smaller_3(ptr noalias %P, i1 %c) {
|
||||||
; CHECK-LABEL: @second_store_smaller_3(
|
; CHECK-LABEL: @second_store_smaller_3(
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: [[P_I16:%.*]] = bitcast i32* [[P]] to i16*
|
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: [[L1:%.*]] = load i16, i16* [[P_I16]], align 2
|
; CHECK-NEXT: [[L1:%.*]] = load i16, ptr [[P]], align 2
|
||||||
; CHECK-NEXT: call void @use(i16 [[L1]])
|
; CHECK-NEXT: call void @use(i16 [[L1]])
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i16 -31073, i16* [[P_I16]], align 2
|
; CHECK-NEXT: store i16 -31073, ptr [[P]], align 2
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
%P.i16 = bitcast i32* %P to i16*
|
|
||||||
br i1 %c, label %bb1, label %bb2
|
br i1 %c, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
%l1 = load i16, i16* %P.i16
|
%l1 = load i16, ptr %P
|
||||||
call void @use(i16 %l1)
|
call void @use(i16 %l1)
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
store i16 -31073, i16* %P.i16
|
store i16 -31073, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @second_store_smaller_4(i32* noalias %P, i1 %c) {
|
define void @second_store_smaller_4(ptr noalias %P, i1 %c) {
|
||||||
; CHECK-LABEL: @second_store_smaller_4(
|
; CHECK-LABEL: @second_store_smaller_4(
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: [[P_I8:%.*]] = bitcast i32* [[P]] to i8*
|
; CHECK-NEXT: [[L1:%.*]] = load i8, ptr [[P]], align 1
|
||||||
; CHECK-NEXT: [[L1:%.*]] = load i8, i8* [[P_I8]], align 1
|
|
||||||
; CHECK-NEXT: call void @use.i8(i8 [[L1]])
|
; CHECK-NEXT: call void @use.i8(i8 [[L1]])
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: [[P_I16:%.*]] = bitcast i32* [[P]] to i16*
|
; CHECK-NEXT: store i16 -31073, ptr [[P]], align 2
|
||||||
; CHECK-NEXT: store i16 -31073, i16* [[P_I16]], align 2
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 %c, label %bb1, label %bb2
|
br i1 %c, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
%P.i8 = bitcast i32* %P to i8*
|
%l1 = load i8, ptr %P
|
||||||
%l1 = load i8, i8* %P.i8
|
|
||||||
call void @use.i8(i8 %l1)
|
call void @use.i8(i8 %l1)
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
%P.i16 = bitcast i32* %P to i16*
|
store i16 -31073, ptr %P
|
||||||
store i16 -31073, i16* %P.i16
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @second_store_smaller_5(i32* noalias %P, i16 %x, i1 %c) {
|
define void @second_store_smaller_5(ptr noalias %P, i16 %x, i1 %c) {
|
||||||
; CHECK-LABEL: @second_store_smaller_5(
|
; CHECK-LABEL: @second_store_smaller_5(
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: [[P_I16:%.*]] = bitcast i32* [[P]] to i16*
|
; CHECK-NEXT: store i16 [[X:%.*]], ptr [[P]], align 2
|
||||||
; CHECK-NEXT: store i16 [[X:%.*]], i16* [[P_I16]], align 2
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 %c, label %bb1, label %bb2
|
br i1 %c, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
%P.i16 = bitcast i32* %P to i16*
|
store i16 %x, ptr %P
|
||||||
store i16 %x, i16* %P.i16
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @second_store_bigger(i32* noalias %P, i1 %c) {
|
define void @second_store_bigger(ptr noalias %P, i1 %c) {
|
||||||
; CHECK-LABEL: @second_store_bigger(
|
; CHECK-LABEL: @second_store_bigger(
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
|
@ -147,18 +137,16 @@ define void @second_store_bigger(i32* noalias %P, i1 %c) {
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: [[P_I64:%.*]] = bitcast i32* [[P:%.*]] to i64*
|
; CHECK-NEXT: store i64 0, ptr [[P:%.*]], align 8
|
||||||
; CHECK-NEXT: store i64 0, i64* [[P_I64]], align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 %c, label %bb1, label %bb2
|
br i1 %c, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
%P.i64 = bitcast i32* %P to i64*
|
store i64 0, ptr %P
|
||||||
store i64 0, i64* %P.i64
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||||
|
|
||||||
|
|
||||||
define void @test2(i32* noalias %P) {
|
define void @test2(ptr noalias %P) {
|
||||||
; CHECK-LABEL: @test2(
|
; CHECK-LABEL: @test2(
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
|
@ -12,158 +12,156 @@ define void @test2(i32* noalias %P) {
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test3(i32* noalias %P) {
|
define void @test3(ptr noalias %P) {
|
||||||
; CHECK-LABEL: @test3(
|
; CHECK-LABEL: @test3(
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
define void @test7(i32* noalias %P, i32* noalias %Q) {
|
define void @test7(ptr noalias %P, ptr noalias %Q) {
|
||||||
; CHECK-LABEL: @test7(
|
; CHECK-LABEL: @test7(
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[Q:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[Q:%.*]], align 4
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 1, i32* %Q
|
store i32 1, ptr %Q
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
load i32, i32* %P
|
load i32, ptr %P
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
store i32 0, i32* %Q
|
store i32 0, ptr %Q
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test22(i32* %P, i32* noalias %Q, i32* %R) {
|
define i32 @test22(ptr %P, ptr noalias %Q, ptr %R) {
|
||||||
; CHECK-LABEL: @test22(
|
; CHECK-LABEL: @test22(
|
||||||
; CHECK-NEXT: store i32 2, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 2, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: store i32 3, i32* [[Q:%.*]], align 4
|
; CHECK-NEXT: store i32 3, ptr [[Q:%.*]], align 4
|
||||||
; CHECK-NEXT: [[L:%.*]] = load i32, i32* [[R:%.*]], align 4
|
; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[R:%.*]], align 4
|
||||||
; CHECK-NEXT: ret i32 [[L]]
|
; CHECK-NEXT: ret i32 [[L]]
|
||||||
;
|
;
|
||||||
store i32 1, i32* %Q
|
store i32 1, ptr %Q
|
||||||
store i32 2, i32* %P
|
store i32 2, ptr %P
|
||||||
store i32 3, i32* %Q
|
store i32 3, ptr %Q
|
||||||
%l = load i32, i32* %R
|
%l = load i32, ptr %R
|
||||||
ret i32 %l
|
ret i32 %l
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test9(i32* noalias %P) {
|
define void @test9(ptr noalias %P) {
|
||||||
; CHECK-LABEL: @test9(
|
; CHECK-LABEL: @test9(
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
ret void
|
ret void
|
||||||
bb3:
|
bb3:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; We cannot eliminate `store i32 0, i32* %P`, as it is read by the later load.
|
; We cannot eliminate `store i32 0, ptr %P`, as it is read by the later load.
|
||||||
; Make sure that we check the uses of `store i32 1, i32* %P.1 which does not
|
; Make sure that we check the uses of `store i32 1, ptr %P.1 which does not
|
||||||
; alias %P. Note that uses point to the *first* def that may alias.
|
; alias %P. Note that uses point to the *first* def that may alias.
|
||||||
define void @overlapping_read(i32* %P) {
|
define void @overlapping_read(ptr %P) {
|
||||||
; CHECK-LABEL: @overlapping_read(
|
; CHECK-LABEL: @overlapping_read(
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: [[P_1:%.*]] = getelementptr i32, i32* [[P]], i32 1
|
; CHECK-NEXT: [[P_1:%.*]] = getelementptr i32, ptr [[P]], i32 1
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P_1]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P_1]], align 4
|
||||||
; CHECK-NEXT: [[P_64:%.*]] = bitcast i32* [[P]] to i64*
|
; CHECK-NEXT: [[LV:%.*]] = load i64, ptr [[P]], align 8
|
||||||
; CHECK-NEXT: [[LV:%.*]] = load i64, i64* [[P_64]], align 8
|
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 2, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 2, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
%P.1 = getelementptr i32, i32* %P, i32 1
|
%P.1 = getelementptr i32, ptr %P, i32 1
|
||||||
store i32 1, i32* %P.1
|
store i32 1, ptr %P.1
|
||||||
|
|
||||||
%P.64 = bitcast i32* %P to i64*
|
%lv = load i64, ptr %P
|
||||||
%lv = load i64, i64* %P.64
|
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
store i32 2, i32* %P
|
store i32 2, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test10(i32* %P) {
|
define void @test10(ptr %P) {
|
||||||
; CHECK-LABEL: @test10(
|
; CHECK-LABEL: @test10(
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
ret void
|
ret void
|
||||||
|
@ -183,10 +181,10 @@ define void @test11() {
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%P = alloca i32
|
%P = alloca i32
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
ret void
|
ret void
|
||||||
|
@ -195,50 +193,50 @@ bb3:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
define void @test12(i32* %P) {
|
define void @test12(ptr %P) {
|
||||||
; CHECK-LABEL: @test12(
|
; CHECK-LABEL: @test12(
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
ret void
|
ret void
|
||||||
bb3:
|
bb3:
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
define void @test13(i32* %P) {
|
define void @test13(ptr %P) {
|
||||||
; CHECK-LABEL: @test13(
|
; CHECK-LABEL: @test13(
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
ret void
|
ret void
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||||
declare void @unknown_func()
|
declare void @unknown_func()
|
||||||
|
|
||||||
define void @test6_store_same_value(i32* noalias %P) {
|
define void @test6_store_same_value(ptr noalias %P) {
|
||||||
; CHECK-LABEL: @test6_store_same_value(
|
; CHECK-LABEL: @test6_store_same_value(
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
|
@ -14,10 +14,10 @@ define void @test6_store_same_value(i32* noalias %P) {
|
||||||
; CHECK-NEXT: call void @unknown_func()
|
; CHECK-NEXT: call void @unknown_func()
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
|
@ -25,13 +25,13 @@ bb2:
|
||||||
call void @unknown_func()
|
call void @unknown_func()
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test6_store_other_value(i32* noalias %P) {
|
define void @test6_store_other_value(ptr noalias %P) {
|
||||||
; CHECK-LABEL: @test6_store_other_value(
|
; CHECK-LABEL: @test6_store_other_value(
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
|
@ -39,10 +39,10 @@ define void @test6_store_other_value(i32* noalias %P) {
|
||||||
; CHECK-NEXT: call void @unknown_func()
|
; CHECK-NEXT: call void @unknown_func()
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
|
@ -50,11 +50,11 @@ bb2:
|
||||||
call void @unknown_func()
|
call void @unknown_func()
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test23(i32* noalias %P) {
|
define void @test23(ptr noalias %P) {
|
||||||
; CHECK-LABEL: @test23(
|
; CHECK-LABEL: @test23(
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
|
@ -63,23 +63,23 @@ define void @test23(i32* noalias %P) {
|
||||||
; CHECK-NEXT: call void @unknown_func()
|
; CHECK-NEXT: call void @unknown_func()
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
call void @unknown_func()
|
call void @unknown_func()
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
define void @test24(i32* noalias %P) {
|
define void @test24(ptr noalias %P) {
|
||||||
; CHECK-LABEL: @test24(
|
; CHECK-LABEL: @test24(
|
||||||
; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB1:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB1:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
|
@ -88,17 +88,17 @@ define void @test24(i32* noalias %P) {
|
||||||
; CHECK-NEXT: call void @unknown_func()
|
; CHECK-NEXT: call void @unknown_func()
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
br i1 true, label %bb2, label %bb1
|
br i1 true, label %bb2, label %bb1
|
||||||
bb1:
|
bb1:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
call void @unknown_func()
|
call void @unknown_func()
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16
|
||||||
|
|
||||||
; Make sure we do not crash when we encounter unreachable blocks while checking
|
; Make sure we do not crash when we encounter unreachable blocks while checking
|
||||||
; if all paths to DomAccess go through a killing block.
|
; if all paths to DomAccess go through a killing block.
|
||||||
define void @test(float* %ptr, i1 %c.1, i1 %c.2, i1 %c.3) {
|
define void @test(ptr %ptr, i1 %c.1, i1 %c.2, i1 %c.3) {
|
||||||
; CHECK-LABEL: @test(
|
; CHECK-LABEL: @test(
|
||||||
; CHECK-NEXT: bb:
|
; CHECK-NEXT: bb:
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB27:%.*]], label [[BB53:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB27:%.*]], label [[BB53:%.*]]
|
||||||
|
@ -16,12 +16,12 @@ define void @test(float* %ptr, i1 %c.1, i1 %c.2, i1 %c.3) {
|
||||||
; CHECK: bb27:
|
; CHECK: bb27:
|
||||||
; CHECK-NEXT: br i1 [[C_3:%.*]], label [[BB38:%.*]], label [[BB39:%.*]]
|
; CHECK-NEXT: br i1 [[C_3:%.*]], label [[BB38:%.*]], label [[BB39:%.*]]
|
||||||
; CHECK: bb38:
|
; CHECK: bb38:
|
||||||
; CHECK-NEXT: store float 0.000000e+00, float* [[PTR:%.*]], align 4
|
; CHECK-NEXT: store float 0.000000e+00, ptr [[PTR:%.*]], align 4
|
||||||
; CHECK-NEXT: br label [[BB38]]
|
; CHECK-NEXT: br label [[BB38]]
|
||||||
; CHECK: bb39:
|
; CHECK: bb39:
|
||||||
; CHECK-NEXT: br i1 [[C_2]], label [[BB43]], label [[BB38]]
|
; CHECK-NEXT: br i1 [[C_2]], label [[BB43]], label [[BB38]]
|
||||||
; CHECK: bb43:
|
; CHECK: bb43:
|
||||||
; CHECK-NEXT: store float 0.000000e+00, float* [[PTR]], align 4
|
; CHECK-NEXT: store float 0.000000e+00, ptr [[PTR]], align 4
|
||||||
; CHECK-NEXT: br label [[BB50:%.*]]
|
; CHECK-NEXT: br label [[BB50:%.*]]
|
||||||
; CHECK: bb50:
|
; CHECK: bb50:
|
||||||
; CHECK-NEXT: br i1 [[C_3]], label [[BB27]], label [[BB53]]
|
; CHECK-NEXT: br i1 [[C_3]], label [[BB27]], label [[BB53]]
|
||||||
|
@ -41,14 +41,14 @@ bb27: ; preds = %bb50, %bb
|
||||||
br i1 %c.3, label %bb38, label %bb39
|
br i1 %c.3, label %bb38, label %bb39
|
||||||
|
|
||||||
bb38: ; preds = %bb39, %bb38, %bb27
|
bb38: ; preds = %bb39, %bb38, %bb27
|
||||||
store float 0.000000e+00, float* %ptr, align 4
|
store float 0.000000e+00, ptr %ptr, align 4
|
||||||
br label %bb38
|
br label %bb38
|
||||||
|
|
||||||
bb39: ; preds = %bb27
|
bb39: ; preds = %bb27
|
||||||
br i1 %c.2, label %bb43, label %bb38
|
br i1 %c.2, label %bb43, label %bb38
|
||||||
|
|
||||||
bb43: ; preds = %bb39, %bb10
|
bb43: ; preds = %bb39, %bb10
|
||||||
store float 0.000000e+00, float* %ptr, align 4
|
store float 0.000000e+00, ptr %ptr, align 4
|
||||||
br label %bb50
|
br label %bb50
|
||||||
|
|
||||||
bb50: ; preds = %bb43
|
bb50: ; preds = %bb43
|
||||||
|
@ -60,30 +60,30 @@ bb53: ; preds = %bb53, %bb50, %bb22,
|
||||||
|
|
||||||
declare void @exit()
|
declare void @exit()
|
||||||
|
|
||||||
define void @unreachable_exit_with_no_call(i64* noalias %ptr, i1 %c.1) {
|
define void @unreachable_exit_with_no_call(ptr noalias %ptr, i1 %c.1) {
|
||||||
; CHECK-LABEL: @unreachable_exit_with_no_call(
|
; CHECK-LABEL: @unreachable_exit_with_no_call(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||||
; CHECK: if.then:
|
; CHECK: if.then:
|
||||||
; CHECK-NEXT: unreachable
|
; CHECK-NEXT: unreachable
|
||||||
; CHECK: if.end:
|
; CHECK: if.end:
|
||||||
; CHECK-NEXT: store i64 0, i64* [[PTR:%.*]], align 8
|
; CHECK-NEXT: store i64 0, ptr [[PTR:%.*]], align 8
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i64 1, i64* %ptr, align 8
|
store i64 1, ptr %ptr, align 8
|
||||||
br i1 %c.1, label %if.then, label %if.end
|
br i1 %c.1, label %if.then, label %if.end
|
||||||
|
|
||||||
if.then:
|
if.then:
|
||||||
unreachable
|
unreachable
|
||||||
|
|
||||||
if.end:
|
if.end:
|
||||||
store i64 0, i64* %ptr, align 8
|
store i64 0, ptr %ptr, align 8
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Test for PR53800.
|
; Test for PR53800.
|
||||||
define void @unreachable_exit_with_nounwind_call_pr53800(i64* noalias %ptr, i1 %c.1) {
|
define void @unreachable_exit_with_nounwind_call_pr53800(ptr noalias %ptr, i1 %c.1) {
|
||||||
; CHECK-LABEL: @unreachable_exit_with_nounwind_call_pr53800(
|
; CHECK-LABEL: @unreachable_exit_with_nounwind_call_pr53800(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||||
|
@ -91,11 +91,11 @@ define void @unreachable_exit_with_nounwind_call_pr53800(i64* noalias %ptr, i1 %
|
||||||
; CHECK-NEXT: tail call void @exit() #[[ATTR0:[0-9]+]]
|
; CHECK-NEXT: tail call void @exit() #[[ATTR0:[0-9]+]]
|
||||||
; CHECK-NEXT: unreachable
|
; CHECK-NEXT: unreachable
|
||||||
; CHECK: if.end:
|
; CHECK: if.end:
|
||||||
; CHECK-NEXT: store i64 0, i64* [[PTR:%.*]], align 8
|
; CHECK-NEXT: store i64 0, ptr [[PTR:%.*]], align 8
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i64 1, i64* %ptr, align 8
|
store i64 1, ptr %ptr, align 8
|
||||||
br i1 %c.1, label %if.then, label %if.end
|
br i1 %c.1, label %if.then, label %if.end
|
||||||
|
|
||||||
if.then:
|
if.then:
|
||||||
|
@ -103,25 +103,25 @@ if.then:
|
||||||
unreachable
|
unreachable
|
||||||
|
|
||||||
if.end:
|
if.end:
|
||||||
store i64 0, i64* %ptr, align 8
|
store i64 0, ptr %ptr, align 8
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; The call @exit may read %ptr as it is not marked as noalias
|
; The call @exit may read %ptr as it is not marked as noalias
|
||||||
define void @unreachable_exit_and_call_may_read(i64* %ptr, i1 %c.1) {
|
define void @unreachable_exit_and_call_may_read(ptr %ptr, i1 %c.1) {
|
||||||
; CHECK-LABEL: @unreachable_exit_and_call_may_read(
|
; CHECK-LABEL: @unreachable_exit_and_call_may_read(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i64 1, i64* [[PTR:%.*]], align 8
|
; CHECK-NEXT: store i64 1, ptr [[PTR:%.*]], align 8
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||||
; CHECK: if.then:
|
; CHECK: if.then:
|
||||||
; CHECK-NEXT: tail call void @exit() #[[ATTR0]]
|
; CHECK-NEXT: tail call void @exit() #[[ATTR0]]
|
||||||
; CHECK-NEXT: unreachable
|
; CHECK-NEXT: unreachable
|
||||||
; CHECK: if.end:
|
; CHECK: if.end:
|
||||||
; CHECK-NEXT: store i64 0, i64* [[PTR]], align 8
|
; CHECK-NEXT: store i64 0, ptr [[PTR]], align 8
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i64 1, i64* %ptr, align 8
|
store i64 1, ptr %ptr, align 8
|
||||||
br i1 %c.1, label %if.then, label %if.end
|
br i1 %c.1, label %if.then, label %if.end
|
||||||
|
|
||||||
if.then:
|
if.then:
|
||||||
|
@ -129,24 +129,24 @@ if.then:
|
||||||
unreachable
|
unreachable
|
||||||
|
|
||||||
if.end:
|
if.end:
|
||||||
store i64 0, i64* %ptr, align 8
|
store i64 0, ptr %ptr, align 8
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @unreachable_exit_with_may_unwind_call(i64* noalias %ptr, i1 %c.1) {
|
define void @unreachable_exit_with_may_unwind_call(ptr noalias %ptr, i1 %c.1) {
|
||||||
; CHECK-LABEL: @unreachable_exit_with_may_unwind_call(
|
; CHECK-LABEL: @unreachable_exit_with_may_unwind_call(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i64 1, i64* [[PTR:%.*]], align 8
|
; CHECK-NEXT: store i64 1, ptr [[PTR:%.*]], align 8
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||||
; CHECK: if.then:
|
; CHECK: if.then:
|
||||||
; CHECK-NEXT: tail call void @exit()
|
; CHECK-NEXT: tail call void @exit()
|
||||||
; CHECK-NEXT: unreachable
|
; CHECK-NEXT: unreachable
|
||||||
; CHECK: if.end:
|
; CHECK: if.end:
|
||||||
; CHECK-NEXT: store i64 0, i64* [[PTR]], align 8
|
; CHECK-NEXT: store i64 0, ptr [[PTR]], align 8
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i64 1, i64* %ptr, align 8
|
store i64 1, ptr %ptr, align 8
|
||||||
br i1 %c.1, label %if.then, label %if.end
|
br i1 %c.1, label %if.then, label %if.end
|
||||||
|
|
||||||
if.then:
|
if.then:
|
||||||
|
@ -154,15 +154,15 @@ if.then:
|
||||||
unreachable
|
unreachable
|
||||||
|
|
||||||
if.end:
|
if.end:
|
||||||
store i64 0, i64* %ptr, align 8
|
store i64 0, ptr %ptr, align 8
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Cannot remove the store in entry, because it is not dead on the path to e.1
|
; Cannot remove the store in entry, because it is not dead on the path to e.1
|
||||||
define void @unreachable_exit_but_another_exit(i64* noalias %ptr, i1 %c.1, i32 %s, i1 %c.2) {
|
define void @unreachable_exit_but_another_exit(ptr noalias %ptr, i1 %c.1, i32 %s, i1 %c.2) {
|
||||||
; CHECK-LABEL: @unreachable_exit_but_another_exit(
|
; CHECK-LABEL: @unreachable_exit_but_another_exit(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i64 1, i64* [[PTR:%.*]], align 8
|
; CHECK-NEXT: store i64 1, ptr [[PTR:%.*]], align 8
|
||||||
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
; CHECK-NEXT: br i1 [[C_1:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||||
; CHECK: if.then:
|
; CHECK: if.then:
|
||||||
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[E_0:%.*]], label [[E_1:%.*]]
|
; CHECK-NEXT: br i1 [[C_2:%.*]], label [[E_0:%.*]], label [[E_1:%.*]]
|
||||||
|
@ -172,11 +172,11 @@ define void @unreachable_exit_but_another_exit(i64* noalias %ptr, i1 %c.1, i32 %
|
||||||
; CHECK: e.1:
|
; CHECK: e.1:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: if.end:
|
; CHECK: if.end:
|
||||||
; CHECK-NEXT: store i64 0, i64* [[PTR]], align 8
|
; CHECK-NEXT: store i64 0, ptr [[PTR]], align 8
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i64 1, i64* %ptr, align 8
|
store i64 1, ptr %ptr, align 8
|
||||||
br i1 %c.1, label %if.then, label %if.end
|
br i1 %c.1, label %if.then, label %if.end
|
||||||
|
|
||||||
if.then:
|
if.then:
|
||||||
|
@ -190,6 +190,6 @@ e.1:
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
if.end:
|
if.end:
|
||||||
store i64 0, i64* %ptr, align 8
|
store i64 0, ptr %ptr, align 8
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
; RUN: opt -basic-aa -dse -S < %s | FileCheck %s
|
; RUN: opt -basic-aa -dse -S < %s | FileCheck %s
|
||||||
|
|
||||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
|
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind
|
||||||
|
|
||||||
define void @fn(i8* nocapture %buf) #0 {
|
define void @fn(ptr nocapture %buf) #0 {
|
||||||
entry:
|
entry:
|
||||||
|
|
||||||
; We would not eliminate the first memcpy with data layout, and we should not
|
; We would not eliminate the first memcpy with data layout, and we should not
|
||||||
; eliminate it without data layout.
|
; eliminate it without data layout.
|
||||||
; CHECK-LABEL: @fn
|
; CHECK-LABEL: @fn
|
||||||
; CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64
|
; CHECK: tail call void @llvm.memcpy.p0.p0.i64
|
||||||
; CHECK: tail call void @llvm.memcpy.p0i8.p0i8.i64
|
; CHECK: tail call void @llvm.memcpy.p0.p0.i64
|
||||||
; CHECK: ret void
|
; CHECK: ret void
|
||||||
|
|
||||||
%arrayidx = getelementptr i8, i8* %buf, i64 18
|
%arrayidx = getelementptr i8, ptr %buf, i64 18
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %arrayidx, i8* %buf, i64 18, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr %arrayidx, ptr %buf, i64 18, i1 false)
|
||||||
store i8 1, i8* %arrayidx, align 1
|
store i8 1, ptr %arrayidx, align 1
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %buf, i8* %arrayidx, i64 18, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr %buf, ptr %arrayidx, i64 18, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,43 +2,43 @@
|
||||||
; RUN: opt -dse -S < %s | FileCheck %s
|
; RUN: opt -dse -S < %s | FileCheck %s
|
||||||
|
|
||||||
; Make sure invokes are not removed as dead stores.
|
; Make sure invokes are not removed as dead stores.
|
||||||
define void @test_nounwind_invoke() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
|
define void @test_nounwind_invoke() personality ptr @__gxx_personality_v0 {
|
||||||
; CHECK-LABEL: @test_nounwind_invoke(
|
; CHECK-LABEL: @test_nounwind_invoke(
|
||||||
; CHECK-NEXT: bb:
|
; CHECK-NEXT: bb:
|
||||||
; CHECK-NEXT: [[TMP:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[TMP:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: invoke void @foo(i32* [[TMP]])
|
; CHECK-NEXT: invoke void @foo(ptr [[TMP]])
|
||||||
; CHECK-NEXT: to label [[BB1:%.*]] unwind label [[BB2:%.*]]
|
; CHECK-NEXT: to label [[BB1:%.*]] unwind label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i32(i64 4, i32* [[TMP]])
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[TMP]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: [[ABCTMP1:%.*]] = landingpad { i8*, i32 }
|
; CHECK-NEXT: [[ABCTMP1:%.*]] = landingpad { ptr, i32 }
|
||||||
; CHECK-NEXT: cleanup
|
; CHECK-NEXT: cleanup
|
||||||
; CHECK-NEXT: resume { i8*, i32 } [[ABCTMP1]]
|
; CHECK-NEXT: resume { ptr, i32 } [[ABCTMP1]]
|
||||||
;
|
;
|
||||||
bb:
|
bb:
|
||||||
%tmp = alloca i32, align 4
|
%tmp = alloca i32, align 4
|
||||||
; 'foo' is 'argmemonly', meaning it can only write to memory pointed by %tmp.
|
; 'foo' is 'argmemonly', meaning it can only write to memory pointed by %tmp.
|
||||||
; And this def is killed by 'call @llvm.lifetime.end.p0i32' in bb1 without
|
; And this def is killed by 'call @llvm.lifetime.end.p0' in bb1 without
|
||||||
; being used elsewhere, becoming a dead store. But we shouldn't remove this
|
; being used elsewhere, becoming a dead store. But we shouldn't remove this
|
||||||
; because invokes are terminators and thus cannot be removed.
|
; because invokes are terminators and thus cannot be removed.
|
||||||
invoke void @foo(i32* %tmp)
|
invoke void @foo(ptr %tmp)
|
||||||
to label %bb1 unwind label %bb2
|
to label %bb1 unwind label %bb2
|
||||||
|
|
||||||
bb1: ; preds = %bb
|
bb1: ; preds = %bb
|
||||||
call void @llvm.lifetime.end.p0i32(i64 4, i32* %tmp)
|
call void @llvm.lifetime.end.p0(i64 4, ptr %tmp)
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
bb2: ; preds = %bb
|
bb2: ; preds = %bb
|
||||||
%tmp1 = landingpad { i8*, i32 }
|
%tmp1 = landingpad { ptr, i32 }
|
||||||
cleanup
|
cleanup
|
||||||
resume { i8*, i32 } %tmp1
|
resume { ptr, i32 } %tmp1
|
||||||
}
|
}
|
||||||
|
|
||||||
; Function Attrs: argmemonly nocallback nofree nosync nounwind willreturn
|
; Function Attrs: argmemonly nocallback nofree nosync nounwind willreturn
|
||||||
declare void @llvm.lifetime.end.p0i32(i64 immarg, i32* nocapture) #0
|
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #0
|
||||||
; Function Attrs: argmemonly nounwind willreturn
|
; Function Attrs: argmemonly nounwind willreturn
|
||||||
declare void @foo(i32*) #1
|
declare void @foo(ptr) #1
|
||||||
declare i32 @__gxx_personality_v0(...)
|
declare i32 @__gxx_personality_v0(...)
|
||||||
|
|
||||||
attributes #0 = { argmemonly nocallback nofree nosync nounwind willreturn }
|
attributes #0 = { argmemonly nocallback nofree nosync nounwind willreturn }
|
||||||
|
|
|
@ -15,40 +15,35 @@ define void @ArrayTestFullyOverlapping(i64 %0) {
|
||||||
;
|
;
|
||||||
; CHECK-LABEL: @ArrayTestFullyOverlapping(
|
; CHECK-LABEL: @ArrayTestFullyOverlapping(
|
||||||
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP0:%.*]], -8
|
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP0:%.*]], -8
|
||||||
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [0 x i8], [0 x i8]* @BUFFER, i64 0, i64 [[TMP2]]
|
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [0 x i8], ptr @BUFFER, i64 0, i64 [[TMP2]]
|
||||||
; CHECK-NEXT: [[TMP4:%.*]] = bitcast i8* [[TMP3]] to i64*
|
; CHECK-NEXT: store i64 0, ptr [[TMP3]], align 4
|
||||||
; CHECK-NEXT: store i64 0, i64* [[TMP4]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%2 = add i64 %0, -8
|
%2 = add i64 %0, -8
|
||||||
%3 = getelementptr inbounds [0 x i8], [0 x i8]* @BUFFER, i64 0, i64 %2
|
%3 = getelementptr inbounds [0 x i8], ptr @BUFFER, i64 0, i64 %2
|
||||||
%4 = bitcast i8* %3 to i64*
|
%4 = add i64 %0, -4
|
||||||
%5 = add i64 %0, -4
|
%5 = getelementptr inbounds [0 x i8], ptr @BUFFER, i64 0, i64 %4
|
||||||
%6 = getelementptr inbounds [0 x i8], [0 x i8]* @BUFFER, i64 0, i64 %5
|
store i32 1, ptr %5
|
||||||
%7 = bitcast i8* %6 to i32*
|
store i64 0, ptr %3
|
||||||
store i32 1, i32* %7
|
|
||||||
store i64 0, i64* %4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @VectorTestFullyOverlapping(float* %arg, i32 %i) {
|
define void @VectorTestFullyOverlapping(ptr %arg, i32 %i) {
|
||||||
; CHECK-LABEL: @VectorTestFullyOverlapping(
|
; CHECK-LABEL: @VectorTestFullyOverlapping(
|
||||||
; CHECK-NEXT: bb:
|
; CHECK-NEXT: bb:
|
||||||
; CHECK-NEXT: [[I2:%.*]] = zext i32 [[I:%.*]] to i64
|
; CHECK-NEXT: [[I2:%.*]] = zext i32 [[I:%.*]] to i64
|
||||||
; CHECK-NEXT: [[I3:%.*]] = getelementptr inbounds float, float* [[ARG:%.*]], i64 [[I2]]
|
; CHECK-NEXT: [[I3:%.*]] = getelementptr inbounds float, ptr [[ARG:%.*]], i64 [[I2]]
|
||||||
; CHECK-NEXT: [[I4:%.*]] = bitcast float* [[I3]] to <2 x float>*
|
; CHECK-NEXT: store <2 x float> zeroinitializer, ptr [[I3]], align 16
|
||||||
; CHECK-NEXT: store <2 x float> zeroinitializer, <2 x float>* [[I4]], align 16
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
bb:
|
bb:
|
||||||
%i7 = add nuw nsw i32 %i, 1
|
%i7 = add nuw nsw i32 %i, 1
|
||||||
%i8 = zext i32 %i7 to i64
|
%i8 = zext i32 %i7 to i64
|
||||||
%i9 = getelementptr inbounds float, float* %arg, i64 %i8
|
%i9 = getelementptr inbounds float, ptr %arg, i64 %i8
|
||||||
store float 0.0, float* %i9, align 4
|
store float 0.0, ptr %i9, align 4
|
||||||
%i2 = zext i32 %i to i64
|
%i2 = zext i32 %i to i64
|
||||||
%i3 = getelementptr inbounds float, float* %arg, i64 %i2
|
%i3 = getelementptr inbounds float, ptr %arg, i64 %i2
|
||||||
%i4 = bitcast float* %i3 to <2 x float>*
|
store <2 x float> <float 0.0, float 0.0>, ptr %i3, align 16
|
||||||
store <2 x float> <float 0.0, float 0.0>, <2 x float>* %i4, align 16
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,27 +54,23 @@ define void @ArrayTestPartiallyOverlapping(i64 %0) {
|
||||||
;
|
;
|
||||||
; CHECK-LABEL: @ArrayTestPartiallyOverlapping(
|
; CHECK-LABEL: @ArrayTestPartiallyOverlapping(
|
||||||
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP0:%.*]], 10
|
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP0:%.*]], 10
|
||||||
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [0 x i8], [0 x i8]* @BUFFER, i64 0, i64 [[TMP2]]
|
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [0 x i8], ptr @BUFFER, i64 0, i64 [[TMP2]]
|
||||||
; CHECK-NEXT: [[TMP4:%.*]] = bitcast i8* [[TMP3]] to i64*
|
|
||||||
; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[TMP0]], 15
|
; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[TMP0]], 15
|
||||||
; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds [0 x i8], [0 x i8]* @BUFFER, i64 0, i64 [[TMP5]]
|
; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds [0 x i8], ptr @BUFFER, i64 0, i64 [[TMP5]]
|
||||||
; CHECK-NEXT: [[TMP7:%.*]] = bitcast i8* [[TMP6]] to i32*
|
; CHECK-NEXT: store i32 1, ptr [[TMP6]], align 4
|
||||||
; CHECK-NEXT: store i32 1, i32* [[TMP7]], align 4
|
; CHECK-NEXT: store i64 0, ptr [[TMP3]], align 4
|
||||||
; CHECK-NEXT: store i64 0, i64* [[TMP4]], align 4
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%2 = add i64 %0, 10
|
%2 = add i64 %0, 10
|
||||||
%3 = getelementptr inbounds [0 x i8], [0 x i8]* @BUFFER, i64 0, i64 %2
|
%3 = getelementptr inbounds [0 x i8], ptr @BUFFER, i64 0, i64 %2
|
||||||
%4 = bitcast i8* %3 to i64*
|
%4 = add i64 %0, 15
|
||||||
%5 = add i64 %0, 15
|
%5 = getelementptr inbounds [0 x i8], ptr @BUFFER, i64 0, i64 %4
|
||||||
%6 = getelementptr inbounds [0 x i8], [0 x i8]* @BUFFER, i64 0, i64 %5
|
store i32 1, ptr %5
|
||||||
%7 = bitcast i8* %6 to i32*
|
store i64 0, ptr %3
|
||||||
store i32 1, i32* %7
|
|
||||||
store i64 0, i64* %4
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @VectorTestPartiallyOverlapping(float* %arg, i32 %i) {
|
define void @VectorTestPartiallyOverlapping(ptr %arg, i32 %i) {
|
||||||
;
|
;
|
||||||
; The DSE pass will not kill the store because the overlap is partial
|
; The DSE pass will not kill the store because the overlap is partial
|
||||||
; and won't fully clobber the original store.
|
; and won't fully clobber the original store.
|
||||||
|
@ -87,26 +78,22 @@ define void @VectorTestPartiallyOverlapping(float* %arg, i32 %i) {
|
||||||
; CHECK-LABEL: @VectorTestPartiallyOverlapping(
|
; CHECK-LABEL: @VectorTestPartiallyOverlapping(
|
||||||
; CHECK-NEXT: bb:
|
; CHECK-NEXT: bb:
|
||||||
; CHECK-NEXT: [[I2:%.*]] = zext i32 [[I:%.*]] to i64
|
; CHECK-NEXT: [[I2:%.*]] = zext i32 [[I:%.*]] to i64
|
||||||
; CHECK-NEXT: [[I3:%.*]] = getelementptr inbounds float, float* [[ARG:%.*]], i64 [[I2]]
|
; CHECK-NEXT: [[I3:%.*]] = getelementptr inbounds float, ptr [[ARG:%.*]], i64 [[I2]]
|
||||||
; CHECK-NEXT: [[I4:%.*]] = bitcast float* [[I3]] to <2 x float>*
|
; CHECK-NEXT: store <2 x float> <float 1.000000e+00, float 1.000000e+00>, ptr [[I3]], align 16
|
||||||
; CHECK-NEXT: store <2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float>* [[I4]], align 16
|
|
||||||
; CHECK-NEXT: [[I5:%.*]] = add nuw nsw i32 [[I]], 1
|
; CHECK-NEXT: [[I5:%.*]] = add nuw nsw i32 [[I]], 1
|
||||||
; CHECK-NEXT: [[I6:%.*]] = zext i32 [[I5]] to i64
|
; CHECK-NEXT: [[I6:%.*]] = zext i32 [[I5]] to i64
|
||||||
; CHECK-NEXT: [[I7:%.*]] = getelementptr inbounds float, float* [[ARG]], i64 [[I6]]
|
; CHECK-NEXT: [[I7:%.*]] = getelementptr inbounds float, ptr [[ARG]], i64 [[I6]]
|
||||||
; CHECK-NEXT: [[I8:%.*]] = bitcast float* [[I7]] to <2 x float>*
|
; CHECK-NEXT: store <2 x float> zeroinitializer, ptr [[I7]], align 16
|
||||||
; CHECK-NEXT: store <2 x float> zeroinitializer, <2 x float>* [[I8]], align 16
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
bb:
|
bb:
|
||||||
%i2 = zext i32 %i to i64
|
%i2 = zext i32 %i to i64
|
||||||
%i3 = getelementptr inbounds float, float* %arg, i64 %i2
|
%i3 = getelementptr inbounds float, ptr %arg, i64 %i2
|
||||||
%i4 = bitcast float* %i3 to <2 x float>*
|
store <2 x float> <float 1.000000e+00, float 1.000000e+00>, ptr %i3, align 16
|
||||||
store <2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float>* %i4, align 16
|
|
||||||
%i5 = add nuw nsw i32 %i, 1
|
%i5 = add nuw nsw i32 %i, 1
|
||||||
%i6 = zext i32 %i5 to i64
|
%i6 = zext i32 %i5 to i64
|
||||||
%i7 = getelementptr inbounds float, float* %arg, i64 %i6
|
%i7 = getelementptr inbounds float, ptr %arg, i64 %i6
|
||||||
%i8 = bitcast float* %i7 to <2 x float>*
|
store <2 x float> <float 0.0, float 0.0>, ptr %i7, align 16
|
||||||
store <2 x float> <float 0.0, float 0.0>, <2 x float>* %i8, align 16
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,31 +1,31 @@
|
||||||
; RUN: opt < %s -basic-aa -dse -S | FileCheck %s
|
; RUN: opt < %s -basic-aa -dse -S | FileCheck %s
|
||||||
|
|
||||||
declare noalias i8* @malloc(i64) "malloc-like"
|
declare noalias ptr @malloc(i64) "malloc-like"
|
||||||
|
|
||||||
declare void @foo()
|
declare void @foo()
|
||||||
declare void @bar(i8*)
|
declare void @bar(ptr)
|
||||||
|
|
||||||
define void @test() {
|
define void @test() {
|
||||||
%obj = call i8* @malloc(i64 8)
|
%obj = call ptr @malloc(i64 8)
|
||||||
store i8 0, i8* %obj
|
store i8 0, ptr %obj
|
||||||
; don't remove store. %obj should be treated like it will be read by the @foo.
|
; don't remove store. %obj should be treated like it will be read by the @foo.
|
||||||
; CHECK: store i8 0, i8* %obj
|
; CHECK: store i8 0, ptr %obj
|
||||||
call void @foo() ["deopt" (i8* %obj)]
|
call void @foo() ["deopt" (ptr %obj)]
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test1() {
|
define void @test1() {
|
||||||
%obj = call i8* @malloc(i64 8)
|
%obj = call ptr @malloc(i64 8)
|
||||||
store i8 0, i8* %obj
|
store i8 0, ptr %obj
|
||||||
; CHECK: store i8 0, i8* %obj
|
; CHECK: store i8 0, ptr %obj
|
||||||
call void @bar(i8* nocapture %obj)
|
call void @bar(ptr nocapture %obj)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test2() {
|
define void @test2() {
|
||||||
%obj = call i8* @malloc(i64 8)
|
%obj = call ptr @malloc(i64 8)
|
||||||
store i8 0, i8* %obj
|
store i8 0, ptr %obj
|
||||||
; CHECK-NOT: store i8 0, i8* %obj
|
; CHECK-NOT: store i8 0, ptr %obj
|
||||||
call void @foo()
|
call void @foo()
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -35,21 +35,21 @@ define void @test3() {
|
||||||
%s = alloca i64
|
%s = alloca i64
|
||||||
; Verify that this first store is not considered killed by the second one
|
; Verify that this first store is not considered killed by the second one
|
||||||
; since it could be observed from the deopt continuation.
|
; since it could be observed from the deopt continuation.
|
||||||
; CHECK: store i64 1, i64* %s
|
; CHECK: store i64 1, ptr %s
|
||||||
store i64 1, i64* %s
|
store i64 1, ptr %s
|
||||||
call void @foo() [ "deopt"(i64* %s) ]
|
call void @foo() [ "deopt"(ptr %s) ]
|
||||||
store i64 0, i64* %s
|
store i64 0, ptr %s
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare noalias i8* @calloc(i64, i64) inaccessiblememonly allockind("alloc,zeroed")
|
declare noalias ptr @calloc(i64, i64) inaccessiblememonly allockind("alloc,zeroed")
|
||||||
|
|
||||||
define void @test4() {
|
define void @test4() {
|
||||||
; CHECK-LABEL: @test4
|
; CHECK-LABEL: @test4
|
||||||
%local_obj = call i8* @calloc(i64 1, i64 4)
|
%local_obj = call ptr @calloc(i64 1, i64 4)
|
||||||
call void @foo() ["deopt" (i8* %local_obj)]
|
call void @foo() ["deopt" (ptr %local_obj)]
|
||||||
store i8 0, i8* %local_obj, align 4
|
store i8 0, ptr %local_obj, align 4
|
||||||
; CHECK-NOT: store i8 0, i8* %local_obj, align 4
|
; CHECK-NOT: store i8 0, ptr %local_obj, align 4
|
||||||
call void @bar(i8* nocapture %local_obj)
|
call void @bar(ptr nocapture %local_obj)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||||
; RUN: opt -dse -S %s | FileCheck %s
|
; RUN: opt -dse -S %s | FileCheck %s
|
||||||
|
|
||||||
declare void @use_pointer(i32*)
|
declare void @use_pointer(ptr)
|
||||||
|
|
||||||
; Out-of-bounds stores can be considered killing any other stores to the same
|
; Out-of-bounds stores can be considered killing any other stores to the same
|
||||||
; object in the same BB, because they are UB and guaranteed to execute. Note
|
; object in the same BB, because they are UB and guaranteed to execute. Note
|
||||||
|
@ -10,19 +10,16 @@ declare void @use_pointer(i32*)
|
||||||
define i32 @test_out_of_bounds_store_local(i1 %c) {
|
define i32 @test_out_of_bounds_store_local(i1 %c) {
|
||||||
; CHECK-LABEL: @test_out_of_bounds_store_local(
|
; CHECK-LABEL: @test_out_of_bounds_store_local(
|
||||||
; CHECK-NEXT: [[D:%.*]] = alloca [1 x i32], align 4
|
; CHECK-NEXT: [[D:%.*]] = alloca [1 x i32], align 4
|
||||||
; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds [1 x i32], [1 x i32]* [[D]], i64 0, i64 1
|
; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds [1 x i32], ptr [[D]], i64 0, i64 1
|
||||||
; CHECK-NEXT: store i32 20, i32* [[ARRAYIDX_1]], align 4
|
; CHECK-NEXT: store i32 20, ptr [[ARRAYIDX_1]], align 4
|
||||||
; CHECK-NEXT: [[BC:%.*]] = bitcast [1 x i32]* [[D]] to i32*
|
; CHECK-NEXT: call void @use_pointer(ptr [[D]])
|
||||||
; CHECK-NEXT: call void @use_pointer(i32* [[BC]])
|
|
||||||
; CHECK-NEXT: ret i32 0
|
; CHECK-NEXT: ret i32 0
|
||||||
;
|
;
|
||||||
%d = alloca [1 x i32], align 4
|
%d = alloca [1 x i32], align 4
|
||||||
%arrayidx = getelementptr inbounds [1 x i32], [1 x i32]* %d, i64 0, i64 0
|
store i32 10, ptr %d, align 4
|
||||||
store i32 10, i32* %arrayidx, align 4
|
%arrayidx.1 = getelementptr inbounds [1 x i32], ptr %d, i64 0, i64 1
|
||||||
%arrayidx.1 = getelementptr inbounds [1 x i32], [1 x i32]* %d, i64 0, i64 1
|
store i32 20, ptr %arrayidx.1, align 4
|
||||||
store i32 20, i32* %arrayidx.1, align 4
|
call void @use_pointer(ptr %d)
|
||||||
%bc = bitcast [1 x i32]* %d to i32*
|
|
||||||
call void @use_pointer(i32* %bc)
|
|
||||||
ret i32 0
|
ret i32 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,25 +30,21 @@ define i32 @test_out_of_bounds_store_local(i1 %c) {
|
||||||
define i32 @test_out_of_bounds_store_local_larger_object(i1 %c) {
|
define i32 @test_out_of_bounds_store_local_larger_object(i1 %c) {
|
||||||
; CHECK-LABEL: @test_out_of_bounds_store_local_larger_object(
|
; CHECK-LABEL: @test_out_of_bounds_store_local_larger_object(
|
||||||
; CHECK-NEXT: [[D:%.*]] = alloca [2 x i32], align 4
|
; CHECK-NEXT: [[D:%.*]] = alloca [2 x i32], align 4
|
||||||
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[D]], i64 0, i64 0
|
; CHECK-NEXT: store i32 10, ptr [[D]], align 4
|
||||||
; CHECK-NEXT: store i32 10, i32* [[ARRAYIDX]], align 4
|
; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[D]], i64 0, i64 1
|
||||||
; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[D]], i64 0, i64 1
|
; CHECK-NEXT: store i32 20, ptr [[ARRAYIDX_1]], align 4
|
||||||
; CHECK-NEXT: store i32 20, i32* [[ARRAYIDX_1]], align 4
|
; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds [2 x i32], ptr [[D]], i64 0, i64 2
|
||||||
; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[D]], i64 0, i64 2
|
; CHECK-NEXT: store i32 30, ptr [[ARRAYIDX_2]], align 4
|
||||||
; CHECK-NEXT: store i32 30, i32* [[ARRAYIDX_2]], align 4
|
; CHECK-NEXT: call void @use_pointer(ptr [[D]])
|
||||||
; CHECK-NEXT: [[BC:%.*]] = bitcast [2 x i32]* [[D]] to i32*
|
|
||||||
; CHECK-NEXT: call void @use_pointer(i32* [[BC]])
|
|
||||||
; CHECK-NEXT: ret i32 0
|
; CHECK-NEXT: ret i32 0
|
||||||
;
|
;
|
||||||
%d = alloca [2 x i32], align 4
|
%d = alloca [2 x i32], align 4
|
||||||
%arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* %d, i64 0, i64 0
|
store i32 10, ptr %d, align 4
|
||||||
store i32 10, i32* %arrayidx, align 4
|
%arrayidx.1 = getelementptr inbounds [2 x i32], ptr %d, i64 0, i64 1
|
||||||
%arrayidx.1 = getelementptr inbounds [2 x i32], [2 x i32]* %d, i64 0, i64 1
|
store i32 20, ptr %arrayidx.1, align 4
|
||||||
store i32 20, i32* %arrayidx.1, align 4
|
%arrayidx.2 = getelementptr inbounds [2 x i32], ptr %d, i64 0, i64 2
|
||||||
%arrayidx.2 = getelementptr inbounds [2 x i32], [2 x i32]* %d, i64 0, i64 2
|
store i32 30, ptr %arrayidx.2, align 4
|
||||||
store i32 30, i32* %arrayidx.2, align 4
|
call void @use_pointer(ptr %d)
|
||||||
%bc = bitcast [2 x i32]* %d to i32*
|
|
||||||
call void @use_pointer(i32* %bc)
|
|
||||||
ret i32 0
|
ret i32 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,36 +58,32 @@ define i32 @test_out_of_bounds_store_nonlocal(i1 %c) {
|
||||||
; CHECK-NEXT: [[D:%.*]] = alloca [1 x i32], align 4
|
; CHECK-NEXT: [[D:%.*]] = alloca [1 x i32], align 4
|
||||||
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
|
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
|
||||||
; CHECK: for.body:
|
; CHECK: for.body:
|
||||||
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1 x i32], [1 x i32]* [[D]], i64 0, i64 0
|
; CHECK-NEXT: store i32 10, ptr [[D]], align 4
|
||||||
; CHECK-NEXT: store i32 10, i32* [[ARRAYIDX]], align 4
|
|
||||||
; CHECK-NEXT: br label [[FOR_INC:%.*]]
|
; CHECK-NEXT: br label [[FOR_INC:%.*]]
|
||||||
; CHECK: for.inc:
|
; CHECK: for.inc:
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[FOR_BODY_1:%.*]], label [[FOR_END:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[FOR_BODY_1:%.*]], label [[FOR_END:%.*]]
|
||||||
; CHECK: for.body.1:
|
; CHECK: for.body.1:
|
||||||
; CHECK-NEXT: ret i32 1
|
; CHECK-NEXT: ret i32 1
|
||||||
; CHECK: for.end:
|
; CHECK: for.end:
|
||||||
; CHECK-NEXT: [[BC:%.*]] = bitcast [1 x i32]* [[D]] to i32*
|
; CHECK-NEXT: call void @use_pointer(ptr [[D]])
|
||||||
; CHECK-NEXT: call void @use_pointer(i32* [[BC]])
|
|
||||||
; CHECK-NEXT: ret i32 0
|
; CHECK-NEXT: ret i32 0
|
||||||
;
|
;
|
||||||
%d = alloca [1 x i32], align 4
|
%d = alloca [1 x i32], align 4
|
||||||
br label %for.body
|
br label %for.body
|
||||||
|
|
||||||
for.body: ; preds = %for.cond
|
for.body: ; preds = %for.cond
|
||||||
%arrayidx = getelementptr inbounds [1 x i32], [1 x i32]* %d, i64 0, i64 0
|
store i32 10, ptr %d, align 4
|
||||||
store i32 10, i32* %arrayidx, align 4
|
|
||||||
br label %for.inc
|
br label %for.inc
|
||||||
|
|
||||||
for.inc: ; preds = %for.body
|
for.inc: ; preds = %for.body
|
||||||
br i1 %c, label %for.body.1, label %for.end
|
br i1 %c, label %for.body.1, label %for.end
|
||||||
|
|
||||||
for.body.1: ; preds = %for.inc
|
for.body.1: ; preds = %for.inc
|
||||||
%arrayidx.1 = getelementptr inbounds [1 x i32], [1 x i32]* %d, i64 0, i64 1
|
%arrayidx.1 = getelementptr inbounds [1 x i32], ptr %d, i64 0, i64 1
|
||||||
store i32 20, i32* %arrayidx.1, align 4
|
store i32 20, ptr %arrayidx.1, align 4
|
||||||
ret i32 1
|
ret i32 1
|
||||||
|
|
||||||
for.end: ; preds = %for.inc
|
for.end: ; preds = %for.inc
|
||||||
%bc = bitcast [1 x i32]* %d to i32*
|
call void @use_pointer(ptr %d)
|
||||||
call void @use_pointer(i32* %bc)
|
|
||||||
ret i32 0
|
ret i32 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,68 +2,64 @@
|
||||||
; RUN: opt < %s -basic-aa -dse -S | FileCheck %s
|
; RUN: opt < %s -basic-aa -dse -S | FileCheck %s
|
||||||
; RUN: opt < %s -aa-pipeline=basic-aa -passes=dse -S | FileCheck %s
|
; RUN: opt < %s -aa-pipeline=basic-aa -passes=dse -S | FileCheck %s
|
||||||
|
|
||||||
declare void @use(i64*)
|
declare void @use(ptr)
|
||||||
|
|
||||||
define void @test1() {
|
define void @test1() {
|
||||||
; CHECK-LABEL: @test1(
|
; CHECK-LABEL: @test1(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i64, align 8
|
; CHECK-NEXT: [[A:%.*]] = alloca i64, align 8
|
||||||
; CHECK-NEXT: call void @use(i64* [[A]])
|
; CHECK-NEXT: call void @use(ptr [[A]])
|
||||||
; CHECK-NEXT: [[PTR1:%.*]] = bitcast i64* [[A]] to i8*
|
; CHECK-NEXT: [[PTR2:%.*]] = getelementptr i8, ptr [[A]], i32 1
|
||||||
; CHECK-NEXT: [[PTR2:%.*]] = getelementptr i8, i8* [[PTR1]], i32 1
|
; CHECK-NEXT: store i8 10, ptr [[A]], align 1
|
||||||
; CHECK-NEXT: store i8 10, i8* [[PTR1]], align 1
|
; CHECK-NEXT: store i8 20, ptr [[PTR2]], align 1
|
||||||
; CHECK-NEXT: store i8 20, i8* [[PTR2]], align 1
|
; CHECK-NEXT: [[LV:%.*]] = load i64, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: [[LV:%.*]] = load i64, i64* [[A]], align 4
|
; CHECK-NEXT: store i8 0, ptr [[A]], align 1
|
||||||
; CHECK-NEXT: store i8 0, i8* [[PTR1]], align 1
|
; CHECK-NEXT: call void @use(ptr [[A]])
|
||||||
; CHECK-NEXT: call void @use(i64* [[A]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca i64
|
%a = alloca i64
|
||||||
call void @use(i64* %a)
|
call void @use(ptr %a)
|
||||||
%ptr1 = bitcast i64* %a to i8*
|
%ptr2 = getelementptr i8, ptr %a, i32 1
|
||||||
%ptr2 = getelementptr i8, i8* %ptr1, i32 1
|
|
||||||
|
|
||||||
store i8 10, i8* %ptr1
|
store i8 10, ptr %a
|
||||||
store i8 20, i8* %ptr2
|
store i8 20, ptr %ptr2
|
||||||
%lv = load i64, i64* %a
|
%lv = load i64, ptr %a
|
||||||
store i8 0, i8* %ptr1
|
store i8 0, ptr %a
|
||||||
|
|
||||||
call void @use(i64* %a)
|
call void @use(ptr %a)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test2() {
|
define void @test2() {
|
||||||
; CHECK-LABEL: @test2(
|
; CHECK-LABEL: @test2(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i64, align 8
|
; CHECK-NEXT: [[A:%.*]] = alloca i64, align 8
|
||||||
; CHECK-NEXT: call void @use(i64* [[A]])
|
; CHECK-NEXT: call void @use(ptr [[A]])
|
||||||
; CHECK-NEXT: [[PTR1:%.*]] = bitcast i64* [[A]] to i8*
|
; CHECK-NEXT: [[PTR2:%.*]] = getelementptr i8, ptr [[A]], i32 1
|
||||||
; CHECK-NEXT: [[PTR2:%.*]] = getelementptr i8, i8* [[PTR1]], i32 1
|
; CHECK-NEXT: store i8 10, ptr [[A]], align 1
|
||||||
; CHECK-NEXT: store i8 10, i8* [[PTR1]], align 1
|
; CHECK-NEXT: store i8 20, ptr [[PTR2]], align 1
|
||||||
; CHECK-NEXT: store i8 20, i8* [[PTR2]], align 1
|
|
||||||
; CHECK-NEXT: br i1 undef, label [[BB1:%.*]], label [[END:%.*]]
|
; CHECK-NEXT: br i1 undef, label [[BB1:%.*]], label [[END:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: [[LV:%.*]] = load i64, i64* [[A]], align 4
|
; CHECK-NEXT: [[LV:%.*]] = load i64, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: br label [[END]]
|
; CHECK-NEXT: br label [[END]]
|
||||||
; CHECK: end:
|
; CHECK: end:
|
||||||
; CHECK-NEXT: store i8 0, i8* [[PTR1]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[A]], align 1
|
||||||
; CHECK-NEXT: call void @use(i64* [[A]])
|
; CHECK-NEXT: call void @use(ptr [[A]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca i64
|
%a = alloca i64
|
||||||
call void @use(i64* %a)
|
call void @use(ptr %a)
|
||||||
%ptr1 = bitcast i64* %a to i8*
|
%ptr2 = getelementptr i8, ptr %a, i32 1
|
||||||
%ptr2 = getelementptr i8, i8* %ptr1, i32 1
|
|
||||||
|
|
||||||
store i8 10, i8* %ptr1
|
store i8 10, ptr %a
|
||||||
store i8 20, i8* %ptr2
|
store i8 20, ptr %ptr2
|
||||||
br i1 undef, label %bb1, label %end
|
br i1 undef, label %bb1, label %end
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
%lv = load i64, i64* %a
|
%lv = load i64, ptr %a
|
||||||
br label %end
|
br label %end
|
||||||
|
|
||||||
end:
|
end:
|
||||||
store i8 0, i8* %ptr1
|
store i8 0, ptr %a
|
||||||
call void @use(i64* %a)
|
call void @use(ptr %a)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,57 +67,55 @@ end:
|
||||||
define void @test3(i1 %c) {
|
define void @test3(i1 %c) {
|
||||||
; CHECK-LABEL: @test3(
|
; CHECK-LABEL: @test3(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca [2 x i8], align 1
|
; CHECK-NEXT: [[A:%.*]] = alloca [2 x i8], align 1
|
||||||
; CHECK-NEXT: [[A1:%.*]] = getelementptr [2 x i8], [2 x i8]* [[A]], i32 0, i32 1
|
; CHECK-NEXT: [[A1:%.*]] = getelementptr [2 x i8], ptr [[A]], i32 0, i32 1
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
|
||||||
; CHECK: if:
|
; CHECK: if:
|
||||||
; CHECK-NEXT: store [2 x i8] zeroinitializer, [2 x i8]* [[A]], align 1
|
; CHECK-NEXT: store [2 x i8] zeroinitializer, ptr [[A]], align 1
|
||||||
; CHECK-NEXT: br label [[ELSE]]
|
; CHECK-NEXT: br label [[ELSE]]
|
||||||
; CHECK: else:
|
; CHECK: else:
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* [[A1]], align 1
|
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[A1]], align 1
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca [2 x i8]
|
%a = alloca [2 x i8]
|
||||||
%a0 = getelementptr [2 x i8], [2 x i8]* %a, i32 0, i32 0
|
%a1 = getelementptr [2 x i8], ptr %a, i32 0, i32 1
|
||||||
%a1 = getelementptr [2 x i8], [2 x i8]* %a, i32 0, i32 1
|
store i8 1, ptr %a
|
||||||
store i8 1, i8* %a0
|
|
||||||
br i1 %c, label %if, label %else
|
br i1 %c, label %if, label %else
|
||||||
|
|
||||||
if:
|
if:
|
||||||
store [2 x i8] zeroinitializer, [2 x i8]* %a
|
store [2 x i8] zeroinitializer, ptr %a
|
||||||
br label %else
|
br label %else
|
||||||
|
|
||||||
else:
|
else:
|
||||||
load i8, i8* %a1
|
load i8, ptr %a1
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Variation on the previous test case, where only the store to %a0 is dead,
|
; Variation on the previous test case, where only the store to %a is dead,
|
||||||
; but not the one to %a1. This tests for a potential caching bug.
|
; but not the one to %a1. This tests for a potential caching bug.
|
||||||
define void @test4(i1 %c) {
|
define void @test4(i1 %c) {
|
||||||
; CHECK-LABEL: @test4(
|
; CHECK-LABEL: @test4(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca [2 x i8], align 1
|
; CHECK-NEXT: [[A:%.*]] = alloca [2 x i8], align 1
|
||||||
; CHECK-NEXT: [[A1:%.*]] = getelementptr [2 x i8], [2 x i8]* [[A]], i32 0, i32 1
|
; CHECK-NEXT: [[A1:%.*]] = getelementptr [2 x i8], ptr [[A]], i32 0, i32 1
|
||||||
; CHECK-NEXT: store i8 1, i8* [[A1]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[A1]], align 1
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
|
||||||
; CHECK: if:
|
; CHECK: if:
|
||||||
; CHECK-NEXT: store [2 x i8] zeroinitializer, [2 x i8]* [[A]], align 1
|
; CHECK-NEXT: store [2 x i8] zeroinitializer, ptr [[A]], align 1
|
||||||
; CHECK-NEXT: br label [[ELSE]]
|
; CHECK-NEXT: br label [[ELSE]]
|
||||||
; CHECK: else:
|
; CHECK: else:
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* [[A1]], align 1
|
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[A1]], align 1
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca [2 x i8]
|
%a = alloca [2 x i8]
|
||||||
%a0 = getelementptr [2 x i8], [2 x i8]* %a, i32 0, i32 0
|
%a1 = getelementptr [2 x i8], ptr %a, i32 0, i32 1
|
||||||
%a1 = getelementptr [2 x i8], [2 x i8]* %a, i32 0, i32 1
|
store i8 1, ptr %a1
|
||||||
store i8 1, i8* %a1
|
store i8 1, ptr %a
|
||||||
store i8 1, i8* %a0
|
|
||||||
br i1 %c, label %if, label %else
|
br i1 %c, label %if, label %else
|
||||||
|
|
||||||
if:
|
if:
|
||||||
store [2 x i8] zeroinitializer, [2 x i8]* %a
|
store [2 x i8] zeroinitializer, ptr %a
|
||||||
br label %else
|
br label %else
|
||||||
|
|
||||||
else:
|
else:
|
||||||
load i8, i8* %a1
|
load i8, ptr %a1
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,8 @@ define void @memoryphi_translate_1(i1 %c) {
|
||||||
; CHECK: else:
|
; CHECK: else:
|
||||||
; CHECK-NEXT: br label [[END]]
|
; CHECK-NEXT: br label [[END]]
|
||||||
; CHECK: end:
|
; CHECK: end:
|
||||||
; CHECK-NEXT: [[P:%.*]] = phi i8* [ [[A_1]], [[THEN]] ], [ [[A_2]], [[ELSE]] ]
|
; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[A_1]], [[THEN]] ], [ [[A_2]], [[ELSE]] ]
|
||||||
; CHECK-NEXT: store i8 10, i8* [[P]], align 1
|
; CHECK-NEXT: store i8 10, ptr [[P]], align 1
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
@ -24,16 +24,16 @@ entry:
|
||||||
br i1 %c, label %then, label %else
|
br i1 %c, label %then, label %else
|
||||||
|
|
||||||
then:
|
then:
|
||||||
store i8 0, i8* %a.1
|
store i8 0, ptr %a.1
|
||||||
br label %end
|
br label %end
|
||||||
|
|
||||||
else:
|
else:
|
||||||
store i8 9, i8* %a.2
|
store i8 9, ptr %a.2
|
||||||
br label %end
|
br label %end
|
||||||
|
|
||||||
end:
|
end:
|
||||||
%p = phi i8* [ %a.1, %then ], [ %a.2, %else ]
|
%p = phi ptr [ %a.1, %then ], [ %a.2, %else ]
|
||||||
store i8 10, i8* %p
|
store i8 10, ptr %p
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,14 +47,14 @@ define i8 @memoryphi_translate_2(i1 %c) {
|
||||||
; CHECK-NEXT: [[A_2:%.*]] = alloca i8, align 1
|
; CHECK-NEXT: [[A_2:%.*]] = alloca i8, align 1
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
||||||
; CHECK: then:
|
; CHECK: then:
|
||||||
; CHECK-NEXT: store i8 0, i8* [[A_1]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[A_1]], align 1
|
||||||
; CHECK-NEXT: br label [[END:%.*]]
|
; CHECK-NEXT: br label [[END:%.*]]
|
||||||
; CHECK: else:
|
; CHECK: else:
|
||||||
; CHECK-NEXT: br label [[END]]
|
; CHECK-NEXT: br label [[END]]
|
||||||
; CHECK: end:
|
; CHECK: end:
|
||||||
; CHECK-NEXT: [[P:%.*]] = phi i8* [ [[A_1]], [[THEN]] ], [ [[A_2]], [[ELSE]] ]
|
; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[A_1]], [[THEN]] ], [ [[A_2]], [[ELSE]] ]
|
||||||
; CHECK-NEXT: [[L:%.*]] = load i8, i8* [[A_1]], align 1
|
; CHECK-NEXT: [[L:%.*]] = load i8, ptr [[A_1]], align 1
|
||||||
; CHECK-NEXT: store i8 10, i8* [[P]], align 1
|
; CHECK-NEXT: store i8 10, ptr [[P]], align 1
|
||||||
; CHECK-NEXT: ret i8 [[L]]
|
; CHECK-NEXT: ret i8 [[L]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
@ -63,17 +63,17 @@ entry:
|
||||||
br i1 %c, label %then, label %else
|
br i1 %c, label %then, label %else
|
||||||
|
|
||||||
then:
|
then:
|
||||||
store i8 0, i8* %a.1
|
store i8 0, ptr %a.1
|
||||||
br label %end
|
br label %end
|
||||||
|
|
||||||
else:
|
else:
|
||||||
store i8 9, i8* %a.2
|
store i8 9, ptr %a.2
|
||||||
br label %end
|
br label %end
|
||||||
|
|
||||||
end:
|
end:
|
||||||
%p = phi i8* [ %a.1, %then ], [ %a.2, %else ]
|
%p = phi ptr [ %a.1, %then ], [ %a.2, %else ]
|
||||||
%l = load i8, i8* %a.1
|
%l = load i8, ptr %a.1
|
||||||
store i8 10, i8* %p
|
store i8 10, ptr %p
|
||||||
ret i8 %l
|
ret i8 %l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,12 +89,12 @@ define i8 @memoryphi_translate_3(i1 %c) {
|
||||||
; CHECK: then:
|
; CHECK: then:
|
||||||
; CHECK-NEXT: br label [[END:%.*]]
|
; CHECK-NEXT: br label [[END:%.*]]
|
||||||
; CHECK: else:
|
; CHECK: else:
|
||||||
; CHECK-NEXT: store i8 9, i8* [[A_2]], align 1
|
; CHECK-NEXT: store i8 9, ptr [[A_2]], align 1
|
||||||
; CHECK-NEXT: br label [[END]]
|
; CHECK-NEXT: br label [[END]]
|
||||||
; CHECK: end:
|
; CHECK: end:
|
||||||
; CHECK-NEXT: [[P:%.*]] = phi i8* [ [[A_1]], [[THEN]] ], [ [[A_2]], [[ELSE]] ]
|
; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[A_1]], [[THEN]] ], [ [[A_2]], [[ELSE]] ]
|
||||||
; CHECK-NEXT: [[L:%.*]] = load i8, i8* [[A_2]], align 1
|
; CHECK-NEXT: [[L:%.*]] = load i8, ptr [[A_2]], align 1
|
||||||
; CHECK-NEXT: store i8 10, i8* [[P]], align 1
|
; CHECK-NEXT: store i8 10, ptr [[P]], align 1
|
||||||
; CHECK-NEXT: ret i8 [[L]]
|
; CHECK-NEXT: ret i8 [[L]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
@ -103,17 +103,17 @@ entry:
|
||||||
br i1 %c, label %then, label %else
|
br i1 %c, label %then, label %else
|
||||||
|
|
||||||
then:
|
then:
|
||||||
store i8 0, i8* %a.1
|
store i8 0, ptr %a.1
|
||||||
br label %end
|
br label %end
|
||||||
|
|
||||||
else:
|
else:
|
||||||
store i8 9, i8* %a.2
|
store i8 9, ptr %a.2
|
||||||
br label %end
|
br label %end
|
||||||
|
|
||||||
end:
|
end:
|
||||||
%p = phi i8* [ %a.1, %then ], [ %a.2, %else ]
|
%p = phi ptr [ %a.1, %then ], [ %a.2, %else ]
|
||||||
%l = load i8, i8* %a.2
|
%l = load i8, ptr %a.2
|
||||||
store i8 10, i8* %p
|
store i8 10, ptr %p
|
||||||
ret i8 %l
|
ret i8 %l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,15 +125,15 @@ define i8 @memoryphi_translate_4(i1 %c) {
|
||||||
; CHECK-NEXT: [[A_2:%.*]] = alloca i8, align 1
|
; CHECK-NEXT: [[A_2:%.*]] = alloca i8, align 1
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
||||||
; CHECK: then:
|
; CHECK: then:
|
||||||
; CHECK-NEXT: store i8 0, i8* [[A_1]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[A_1]], align 1
|
||||||
; CHECK-NEXT: br label [[END:%.*]]
|
; CHECK-NEXT: br label [[END:%.*]]
|
||||||
; CHECK: else:
|
; CHECK: else:
|
||||||
; CHECK-NEXT: store i8 9, i8* [[A_2]], align 1
|
; CHECK-NEXT: store i8 9, ptr [[A_2]], align 1
|
||||||
; CHECK-NEXT: br label [[END]]
|
; CHECK-NEXT: br label [[END]]
|
||||||
; CHECK: end:
|
; CHECK: end:
|
||||||
; CHECK-NEXT: [[P:%.*]] = phi i8* [ [[A_1]], [[THEN]] ], [ [[A_2]], [[ELSE]] ]
|
; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[A_1]], [[THEN]] ], [ [[A_2]], [[ELSE]] ]
|
||||||
; CHECK-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 1
|
; CHECK-NEXT: [[L:%.*]] = load i8, ptr [[P]], align 1
|
||||||
; CHECK-NEXT: store i8 10, i8* [[P]], align 1
|
; CHECK-NEXT: store i8 10, ptr [[P]], align 1
|
||||||
; CHECK-NEXT: ret i8 [[L]]
|
; CHECK-NEXT: ret i8 [[L]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
@ -142,17 +142,17 @@ entry:
|
||||||
br i1 %c, label %then, label %else
|
br i1 %c, label %then, label %else
|
||||||
|
|
||||||
then:
|
then:
|
||||||
store i8 0, i8* %a.1
|
store i8 0, ptr %a.1
|
||||||
br label %end
|
br label %end
|
||||||
|
|
||||||
else:
|
else:
|
||||||
store i8 9, i8* %a.2
|
store i8 9, ptr %a.2
|
||||||
br label %end
|
br label %end
|
||||||
|
|
||||||
end:
|
end:
|
||||||
%p = phi i8* [ %a.1, %then ], [ %a.2, %else ]
|
%p = phi ptr [ %a.1, %then ], [ %a.2, %else ]
|
||||||
%l = load i8, i8* %p
|
%l = load i8, ptr %p
|
||||||
store i8 10, i8* %p
|
store i8 10, ptr %p
|
||||||
ret i8 %l
|
ret i8 %l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,31 +162,31 @@ define void @memoryphi_translate_5(i1 %cond) {
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1
|
; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1
|
||||||
; CHECK-NEXT: [[B:%.*]] = alloca i8, align 1
|
; CHECK-NEXT: [[B:%.*]] = alloca i8, align 1
|
||||||
; CHECK-NEXT: store i8 0, i8* [[A]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[A]], align 1
|
||||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
|
; CHECK-NEXT: br i1 [[COND:%.*]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
|
||||||
; CHECK: cond.true:
|
; CHECK: cond.true:
|
||||||
; CHECK-NEXT: br label [[COND_END]]
|
; CHECK-NEXT: br label [[COND_END]]
|
||||||
; CHECK: cond.end:
|
; CHECK: cond.end:
|
||||||
; CHECK-NEXT: [[P:%.*]] = phi i8* [ [[B]], [[COND_TRUE]] ], [ [[A]], [[ENTRY:%.*]] ]
|
; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[B]], [[COND_TRUE]] ], [ [[A]], [[ENTRY:%.*]] ]
|
||||||
; CHECK-NEXT: store i8 0, i8* [[P]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[P]], align 1
|
||||||
; CHECK-NEXT: call void @use(i8* [[P]])
|
; CHECK-NEXT: call void @use(ptr [[P]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8
|
%a = alloca i8
|
||||||
%b = alloca i8
|
%b = alloca i8
|
||||||
%c = alloca i8
|
%c = alloca i8
|
||||||
store i8 0, i8* %a
|
store i8 0, ptr %a
|
||||||
br i1 %cond, label %cond.true, label %cond.end
|
br i1 %cond, label %cond.true, label %cond.end
|
||||||
|
|
||||||
cond.true:
|
cond.true:
|
||||||
store i8 0, i8* %c
|
store i8 0, ptr %c
|
||||||
br label %cond.end
|
br label %cond.end
|
||||||
|
|
||||||
cond.end:
|
cond.end:
|
||||||
%p = phi i8* [ %b, %cond.true ], [ %a, %entry ]
|
%p = phi ptr [ %b, %cond.true ], [ %a, %entry ]
|
||||||
store i8 0, i8* %p
|
store i8 0, ptr %p
|
||||||
call void @use(i8* %p)
|
call void @use(ptr %p)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,35 +198,35 @@ define void @translate_without_memoryphi_1(i1 %cond) {
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1
|
; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1
|
||||||
; CHECK-NEXT: [[B:%.*]] = alloca i8, align 1
|
; CHECK-NEXT: [[B:%.*]] = alloca i8, align 1
|
||||||
; CHECK-NEXT: store i8 0, i8* [[A]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[A]], align 1
|
||||||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
|
; CHECK-NEXT: br i1 [[COND:%.*]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
|
||||||
; CHECK: cond.true:
|
; CHECK: cond.true:
|
||||||
; CHECK-NEXT: br label [[COND_END]]
|
; CHECK-NEXT: br label [[COND_END]]
|
||||||
; CHECK: cond.end:
|
; CHECK: cond.end:
|
||||||
; CHECK-NEXT: [[P:%.*]] = phi i8* [ [[B]], [[COND_TRUE]] ], [ [[A]], [[ENTRY:%.*]] ]
|
; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[B]], [[COND_TRUE]] ], [ [[A]], [[ENTRY:%.*]] ]
|
||||||
; CHECK-NEXT: store i8 0, i8* [[P]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[P]], align 1
|
||||||
; CHECK-NEXT: call void @use(i8* [[P]])
|
; CHECK-NEXT: call void @use(ptr [[P]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%a = alloca i8
|
%a = alloca i8
|
||||||
%b = alloca i8
|
%b = alloca i8
|
||||||
store i8 0, i8* %a
|
store i8 0, ptr %a
|
||||||
br i1 %cond, label %cond.true, label %cond.end
|
br i1 %cond, label %cond.true, label %cond.end
|
||||||
|
|
||||||
cond.true:
|
cond.true:
|
||||||
br label %cond.end
|
br label %cond.end
|
||||||
|
|
||||||
cond.end:
|
cond.end:
|
||||||
%p = phi i8* [ %b, %cond.true ], [ %a, %entry ]
|
%p = phi ptr [ %b, %cond.true ], [ %a, %entry ]
|
||||||
store i8 0, i8* %p
|
store i8 0, ptr %p
|
||||||
call void @use(i8* %p)
|
call void @use(ptr %p)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; In the test, translating through the phi results in a null address. Make sure
|
; In the test, translating through the phi results in a null address. Make sure
|
||||||
; this does not cause a crash.
|
; this does not cause a crash.
|
||||||
define void @test_trans_null(i1 %c, i16* %ptr) {
|
define void @test_trans_null(i1 %c, ptr %ptr) {
|
||||||
; CHECK-LABEL: @test_trans_null(
|
; CHECK-LABEL: @test_trans_null(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
|
||||||
|
@ -234,14 +234,13 @@ define void @test_trans_null(i1 %c, i16* %ptr) {
|
||||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||||
; CHECK: else:
|
; CHECK: else:
|
||||||
; CHECK-NEXT: call void @fn()
|
; CHECK-NEXT: call void @fn()
|
||||||
; CHECK-NEXT: [[BC:%.*]] = bitcast i8* undef to i16*
|
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i16, ptr undef, i64 2
|
||||||
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i16, i16* [[BC]], i64 2
|
; CHECK-NEXT: store i16 8, ptr [[GEP_1]], align 2
|
||||||
; CHECK-NEXT: store i16 8, i16* [[GEP_1]], align 2
|
|
||||||
; CHECK-NEXT: br label [[EXIT]]
|
; CHECK-NEXT: br label [[EXIT]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: [[P:%.*]] = phi i16* [ [[PTR:%.*]], [[THEN]] ], [ [[BC]], [[ELSE]] ]
|
; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[PTR:%.*]], [[THEN]] ], [ undef, [[ELSE]] ]
|
||||||
; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i16, i16* [[P]], i64 2
|
; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i16, ptr [[P]], i64 2
|
||||||
; CHECK-NEXT: store i16 8, i16* [[GEP_2]], align 2
|
; CHECK-NEXT: store i16 8, ptr [[GEP_2]], align 2
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
@ -252,18 +251,17 @@ then:
|
||||||
|
|
||||||
else:
|
else:
|
||||||
call void @fn()
|
call void @fn()
|
||||||
%bc = bitcast i8* undef to i16*
|
%gep.1 = getelementptr inbounds i16, ptr undef, i64 2
|
||||||
%gep.1 = getelementptr inbounds i16, i16* %bc, i64 2
|
store i16 8, ptr %gep.1, align 2
|
||||||
store i16 8, i16* %gep.1, align 2
|
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
%p = phi i16* [ %ptr, %then ], [ %bc, %else ]
|
%p = phi ptr [ %ptr, %then ], [ undef, %else ]
|
||||||
%gep.2 = getelementptr inbounds i16, i16* %p, i64 2
|
%gep.2 = getelementptr inbounds i16, ptr %p, i64 2
|
||||||
store i16 8, i16* %gep.2, align 2
|
store i16 8, ptr %gep.2, align 2
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
declare void @use(i8*)
|
declare void @use(ptr)
|
||||||
declare void @fn()
|
declare void @fn()
|
||||||
|
|
|
@ -3,36 +3,36 @@
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
||||||
define fastcc void @cat_domain(i8* nocapture %name, i8* nocapture %domain, i8**
|
define fastcc void @cat_domain(ptr nocapture %name, ptr nocapture %domain, ptr
|
||||||
nocapture %s) nounwind uwtable {
|
nocapture %s) nounwind uwtable {
|
||||||
entry:
|
entry:
|
||||||
%call = tail call i64 @strlen(i8* %name) nounwind readonly
|
%call = tail call i64 @strlen(ptr %name) nounwind readonly
|
||||||
%call1 = tail call i64 @strlen(i8* %domain) nounwind readonly
|
%call1 = tail call i64 @strlen(ptr %domain) nounwind readonly
|
||||||
%add = add i64 %call, 1
|
%add = add i64 %call, 1
|
||||||
%add2 = add i64 %add, %call1
|
%add2 = add i64 %add, %call1
|
||||||
%add3 = add i64 %add2, 1
|
%add3 = add i64 %add2, 1
|
||||||
%call4 = tail call noalias i8* @malloc(i64 %add3) nounwind
|
%call4 = tail call noalias ptr @malloc(i64 %add3) nounwind
|
||||||
store i8* %call4, i8** %s, align 8
|
store ptr %call4, ptr %s, align 8
|
||||||
%tobool = icmp eq i8* %call4, null
|
%tobool = icmp eq ptr %call4, null
|
||||||
br i1 %tobool, label %return, label %if.end
|
br i1 %tobool, label %return, label %if.end
|
||||||
|
|
||||||
if.end: ; preds = %entry
|
if.end: ; preds = %entry
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %call4, i8* %name, i64 %call, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr %call4, ptr %name, i64 %call, i1 false)
|
||||||
%arrayidx = getelementptr inbounds i8, i8* %call4, i64 %call
|
%arrayidx = getelementptr inbounds i8, ptr %call4, i64 %call
|
||||||
store i8 46, i8* %arrayidx, align 1
|
store i8 46, ptr %arrayidx, align 1
|
||||||
; CHECK: store i8 46
|
; CHECK: store i8 46
|
||||||
%add.ptr5 = getelementptr inbounds i8, i8* %call4, i64 %add
|
%add.ptr5 = getelementptr inbounds i8, ptr %call4, i64 %add
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %add.ptr5, i8* %domain, i64 %call1, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr %add.ptr5, ptr %domain, i64 %call1, i1 false)
|
||||||
%arrayidx8 = getelementptr inbounds i8, i8* %call4, i64 %add2
|
%arrayidx8 = getelementptr inbounds i8, ptr %call4, i64 %add2
|
||||||
store i8 0, i8* %arrayidx8, align 1
|
store i8 0, ptr %arrayidx8, align 1
|
||||||
br label %return
|
br label %return
|
||||||
|
|
||||||
return: ; preds = %if.end, %entry
|
return: ; preds = %if.end, %entry
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i64 @strlen(i8* nocapture) nounwind readonly
|
declare i64 @strlen(ptr nocapture) nounwind readonly
|
||||||
|
|
||||||
declare noalias i8* @malloc(i64) nounwind
|
declare noalias ptr @malloc(i64) nounwind
|
||||||
|
|
||||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) nounwind
|
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
; Reduced test case for PR47285.
|
; Reduced test case for PR47285.
|
||||||
|
|
||||||
; `store i32 9, i32* @b` in %interesting is not killed by `store i32 23, i32* @b`
|
; `store i32 9, ptr @b` in %interesting is not killed by `store i32 23, ptr @b`
|
||||||
; in %killer, because it is not overwritten before reaching the end of the
|
; in %killer, because it is not overwritten before reaching the end of the
|
||||||
; function via %bb.2 -> %no.overwrite.exit.
|
; function via %bb.2 -> %no.overwrite.exit.
|
||||||
|
|
||||||
|
@ -22,24 +22,24 @@ define void @test(i1 %c.0, i1 %c.2, i1 %c.3, i1 %c.4, i1 %c.5, i1 %c.6) {
|
||||||
; CHECK: bb.4:
|
; CHECK: bb.4:
|
||||||
; CHECK-NEXT: br i1 [[C_4:%.*]], label [[BB_5:%.*]], label [[BB_6:%.*]]
|
; CHECK-NEXT: br i1 [[C_4:%.*]], label [[BB_5:%.*]], label [[BB_6:%.*]]
|
||||||
; CHECK: bb.5:
|
; CHECK: bb.5:
|
||||||
; CHECK-NEXT: store i32 99, i32* @b, align 4
|
; CHECK-NEXT: store i32 99, ptr @b, align 4
|
||||||
; CHECK-NEXT: br i1 [[C_3:%.*]], label [[BB_5]], label [[BB_2]]
|
; CHECK-NEXT: br i1 [[C_3:%.*]], label [[BB_5]], label [[BB_2]]
|
||||||
; CHECK: bb.6:
|
; CHECK: bb.6:
|
||||||
; CHECK-NEXT: store i32 91, i32* @b, align 4
|
; CHECK-NEXT: store i32 91, ptr @b, align 4
|
||||||
; CHECK-NEXT: br i1 [[C_5:%.*]], label [[SPLIT_CRIT_EDGE_2:%.*]], label [[BB_2]]
|
; CHECK-NEXT: br i1 [[C_5:%.*]], label [[SPLIT_CRIT_EDGE_2:%.*]], label [[BB_2]]
|
||||||
; CHECK: split_crit_edge.2:
|
; CHECK: split_crit_edge.2:
|
||||||
; CHECK-NEXT: store i32 27, i32* @b, align 4
|
; CHECK-NEXT: store i32 27, ptr @b, align 4
|
||||||
; CHECK-NEXT: br label [[EXIT:%.*]]
|
; CHECK-NEXT: br label [[EXIT:%.*]]
|
||||||
; CHECK: bb.7:
|
; CHECK: bb.7:
|
||||||
; CHECK-NEXT: br i1 [[C_4]], label [[INTERESTING:%.*]], label [[BB_8:%.*]]
|
; CHECK-NEXT: br i1 [[C_4]], label [[INTERESTING:%.*]], label [[BB_8:%.*]]
|
||||||
; CHECK: interesting:
|
; CHECK: interesting:
|
||||||
; CHECK-NEXT: store i32 9, i32* @b, align 4
|
; CHECK-NEXT: store i32 9, ptr @b, align 4
|
||||||
; CHECK-NEXT: br i1 [[C_6:%.*]], label [[KILLER:%.*]], label [[BB_2]]
|
; CHECK-NEXT: br i1 [[C_6:%.*]], label [[KILLER:%.*]], label [[BB_2]]
|
||||||
; CHECK: killer:
|
; CHECK: killer:
|
||||||
; CHECK-NEXT: store i32 23, i32* @b, align 4
|
; CHECK-NEXT: store i32 23, ptr @b, align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb.8:
|
; CHECK: bb.8:
|
||||||
; CHECK-NEXT: store i32 19, i32* @b, align 4
|
; CHECK-NEXT: store i32 19, ptr @b, align 4
|
||||||
; CHECK-NEXT: br i1 [[C_4]], label [[EXIT]], label [[BB_2]]
|
; CHECK-NEXT: br i1 [[C_4]], label [[EXIT]], label [[BB_2]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
|
@ -60,30 +60,30 @@ bb.4: ; preds = %bb.3
|
||||||
br i1 %c.4, label %bb.5, label %bb.6
|
br i1 %c.4, label %bb.5, label %bb.6
|
||||||
|
|
||||||
bb.5: ; preds = %bb.5, %bb.4
|
bb.5: ; preds = %bb.5, %bb.4
|
||||||
store i32 99, i32* @b, align 4
|
store i32 99, ptr @b, align 4
|
||||||
br i1 %c.3, label %bb.5, label %bb.2
|
br i1 %c.3, label %bb.5, label %bb.2
|
||||||
|
|
||||||
bb.6: ; preds = %bb.4
|
bb.6: ; preds = %bb.4
|
||||||
store i32 91, i32* @b, align 4
|
store i32 91, ptr @b, align 4
|
||||||
br i1 %c.5, label %split_crit_edge.2, label %bb.2
|
br i1 %c.5, label %split_crit_edge.2, label %bb.2
|
||||||
|
|
||||||
split_crit_edge.2: ; preds = %bb.6
|
split_crit_edge.2: ; preds = %bb.6
|
||||||
store i32 27, i32* @b, align 4
|
store i32 27, ptr @b, align 4
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
bb.7: ; preds = %bb.3
|
bb.7: ; preds = %bb.3
|
||||||
br i1 %c.4, label %interesting, label %bb.8
|
br i1 %c.4, label %interesting, label %bb.8
|
||||||
|
|
||||||
interesting: ; preds = %bb.7
|
interesting: ; preds = %bb.7
|
||||||
store i32 9, i32* @b, align 4
|
store i32 9, ptr @b, align 4
|
||||||
br i1 %c.6, label %killer, label %bb.2
|
br i1 %c.6, label %killer, label %bb.2
|
||||||
|
|
||||||
killer: ; preds = %interesting
|
killer: ; preds = %interesting
|
||||||
store i32 23, i32* @b, align 4
|
store i32 23, ptr @b, align 4
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
bb.8: ; preds = %bb.7
|
bb.8: ; preds = %bb.7
|
||||||
store i32 19, i32* @b, align 4
|
store i32 19, ptr @b, align 4
|
||||||
br i1 %c.4, label %exit, label %bb.2
|
br i1 %c.4, label %exit, label %bb.2
|
||||||
|
|
||||||
exit: ; preds = %bb.8, %split_crit_edge.2
|
exit: ; preds = %bb.8, %split_crit_edge.2
|
||||||
|
|
|
@ -12,10 +12,10 @@ define i32 @test() {
|
||||||
; CHECK-NEXT: br label [[LOOP_2:%.*]]
|
; CHECK-NEXT: br label [[LOOP_2:%.*]]
|
||||||
; CHECK: loop.2:
|
; CHECK: loop.2:
|
||||||
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[LOOP_1]] ], [ [[IV_NEXT:%.*]], [[LOOP_2]] ]
|
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[LOOP_1]] ], [ [[IV_NEXT:%.*]], [[LOOP_2]] ]
|
||||||
; CHECK-NEXT: [[PTR_1:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* [[M0]], i64 3, i64 [[IV]]
|
; CHECK-NEXT: [[PTR_1:%.*]] = getelementptr inbounds [4 x i32], ptr [[M0]], i64 3, i64 [[IV]]
|
||||||
; CHECK-NEXT: [[PTR_2:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* [[M0]], i64 0, i64 [[IV]]
|
; CHECK-NEXT: [[PTR_2:%.*]] = getelementptr inbounds [4 x i32], ptr [[M0]], i64 0, i64 [[IV]]
|
||||||
; CHECK-NEXT: store i32 20, i32* [[PTR_2]], align 4
|
; CHECK-NEXT: store i32 20, ptr [[PTR_2]], align 4
|
||||||
; CHECK-NEXT: store i32 30, i32* [[PTR_1]], align 4
|
; CHECK-NEXT: store i32 30, ptr [[PTR_1]], align 4
|
||||||
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
|
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
|
||||||
; CHECK-NEXT: [[C_3:%.*]] = call i1 @cond()
|
; CHECK-NEXT: [[C_3:%.*]] = call i1 @cond()
|
||||||
; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_1_LATCH:%.*]], label [[LOOP_2]]
|
; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_1_LATCH:%.*]], label [[LOOP_2]]
|
||||||
|
@ -23,8 +23,8 @@ define i32 @test() {
|
||||||
; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()
|
; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond()
|
||||||
; CHECK-NEXT: br i1 [[C_2]], label [[EXIT:%.*]], label [[LOOP_1]]
|
; CHECK-NEXT: br i1 [[C_2]], label [[EXIT:%.*]], label [[LOOP_1]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: [[PTR_3:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* [[M0]], i64 0, i64 1
|
; CHECK-NEXT: [[PTR_3:%.*]] = getelementptr inbounds [4 x i32], ptr [[M0]], i64 0, i64 1
|
||||||
; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR_3]], align 16
|
; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR_3]], align 16
|
||||||
; CHECK-NEXT: ret i32 [[LV]]
|
; CHECK-NEXT: ret i32 [[LV]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
@ -36,11 +36,11 @@ loop.1:
|
||||||
|
|
||||||
loop.2:
|
loop.2:
|
||||||
%iv = phi i64 [ 0, %loop.1 ], [ %iv.next, %loop.2 ]
|
%iv = phi i64 [ 0, %loop.1 ], [ %iv.next, %loop.2 ]
|
||||||
%ptr.1 = getelementptr inbounds [4 x i32], [4 x i32]* %M0, i64 3, i64 %iv
|
%ptr.1 = getelementptr inbounds [4 x i32], ptr %M0, i64 3, i64 %iv
|
||||||
store i32 10, i32* %ptr.1, align 4
|
store i32 10, ptr %ptr.1, align 4
|
||||||
%ptr.2 = getelementptr inbounds [4 x i32], [4 x i32]* %M0, i64 0, i64 %iv
|
%ptr.2 = getelementptr inbounds [4 x i32], ptr %M0, i64 0, i64 %iv
|
||||||
store i32 20, i32* %ptr.2, align 4
|
store i32 20, ptr %ptr.2, align 4
|
||||||
store i32 30, i32* %ptr.1, align 4
|
store i32 30, ptr %ptr.1, align 4
|
||||||
%iv.next = add nuw nsw i64 %iv, 1
|
%iv.next = add nuw nsw i64 %iv, 1
|
||||||
%c.3 = call i1 @cond()
|
%c.3 = call i1 @cond()
|
||||||
br i1 %c.3, label %loop.1.latch, label %loop.2
|
br i1 %c.3, label %loop.1.latch, label %loop.2
|
||||||
|
@ -50,8 +50,8 @@ loop.1.latch:
|
||||||
br i1 %c.2, label %exit, label %loop.1
|
br i1 %c.2, label %exit, label %loop.1
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
%ptr.3 = getelementptr inbounds [4 x i32], [4 x i32]* %M0, i64 0, i64 1
|
%ptr.3 = getelementptr inbounds [4 x i32], ptr %M0, i64 0, i64 1
|
||||||
%lv = load i32, i32* %ptr.3, align 16
|
%lv = load i32, ptr %ptr.3, align 16
|
||||||
ret i32 %lv
|
ret i32 %lv
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,28 +4,28 @@
|
||||||
; Assume that %p1 != %p2 if and only if %c is true. In that case the noalias
|
; Assume that %p1 != %p2 if and only if %c is true. In that case the noalias
|
||||||
; metadata is correct, but the first store cannot be eliminated, as it may be
|
; metadata is correct, but the first store cannot be eliminated, as it may be
|
||||||
; read-clobbered by the load.
|
; read-clobbered by the load.
|
||||||
define void @test(i1 %c, i8* %p1, i8* %p2) {
|
define void @test(i1 %c, ptr %p1, ptr %p2) {
|
||||||
; CHECK-LABEL: @test(
|
; CHECK-LABEL: @test(
|
||||||
; CHECK-NEXT: store i8 0, i8* [[P1:%.*]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[P1:%.*]], align 1
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* [[P2:%.*]], align 1, !alias.scope !0
|
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[P2:%.*]], align 1, !alias.scope !0
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
|
||||||
; CHECK: if:
|
; CHECK: if:
|
||||||
; CHECK-NEXT: store i8 1, i8* [[P1]], align 1, !noalias !0
|
; CHECK-NEXT: store i8 1, ptr [[P1]], align 1, !noalias !0
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: else:
|
; CHECK: else:
|
||||||
; CHECK-NEXT: store i8 2, i8* [[P1]], align 1
|
; CHECK-NEXT: store i8 2, ptr [[P1]], align 1
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i8 0, i8* %p1
|
store i8 0, ptr %p1
|
||||||
load i8, i8* %p2, !alias.scope !2
|
load i8, ptr %p2, !alias.scope !2
|
||||||
br i1 %c, label %if, label %else
|
br i1 %c, label %if, label %else
|
||||||
|
|
||||||
if:
|
if:
|
||||||
store i8 1, i8* %p1, !noalias !2
|
store i8 1, ptr %p1, !noalias !2
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
else:
|
else:
|
||||||
store i8 2, i8* %p1
|
store i8 2, ptr %p1
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,15 @@
|
||||||
|
|
||||||
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
|
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
|
||||||
|
|
||||||
define void @test1(i32* %Q, i32* %P) {
|
define void @test1(ptr %Q, ptr %P) {
|
||||||
; CHECK-LABEL: @test1(
|
; CHECK-LABEL: @test1(
|
||||||
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[Q:%.*]], i64 4), "nonnull"(i32* [[Q]]), "align"(i32* [[Q]], i64 4) ]
|
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[Q:%.*]], i64 4), "nonnull"(ptr [[Q]]), "align"(ptr [[Q]], i64 4) ]
|
||||||
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P:%.*]], i64 4), "nonnull"(i32* [[P]]), "align"(i32* [[P]], i64 4) ]
|
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P:%.*]], i64 4), "nonnull"(ptr [[P]]), "align"(ptr [[P]], i64 4) ]
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%DEAD = load i32, i32* %Q
|
%DEAD = load i32, ptr %Q
|
||||||
store i32 %DEAD, i32* %P
|
store i32 %DEAD, ptr %P
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,29 +6,29 @@
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||||
|
|
||||||
|
|
||||||
define void @test2(i32* noalias %P, i32* noalias %C, i1 %c) {
|
define void @test2(ptr noalias %P, ptr noalias %C, i1 %c) {
|
||||||
; CHECK-LABEL: @test2(
|
; CHECK-LABEL: @test2(
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: store i32 3, i32* [[C:%.*]]
|
; CHECK-NEXT: store i32 3, ptr [[C:%.*]]
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: store i32 4, i32* [[C]]
|
; CHECK-NEXT: store i32 4, ptr [[C]]
|
||||||
; CHECK-NEXT: br label [[BB3]]
|
; CHECK-NEXT: br label [[BB3]]
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]]
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 1, i32* %P
|
store i32 1, ptr %P
|
||||||
br i1 %c, label %bb1, label %bb2
|
br i1 %c, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
store i32 3, i32* %C
|
store i32 3, ptr %C
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
store i32 4, i32* %C
|
store i32 4, ptr %C
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb3:
|
bb3:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,59 +3,53 @@
|
||||||
|
|
||||||
target datalayout = "E-m:e-p:32:32-i64:32-f64:32:64-a:0:32-n32-S32"
|
target datalayout = "E-m:e-p:32:32-i64:32-f64:32:64-a:0:32-n32-S32"
|
||||||
|
|
||||||
%struct.ilist = type { i32, %struct.ilist* }
|
%struct.ilist = type { i32, ptr }
|
||||||
|
|
||||||
; There is no dead store in this test. Make sure no store is deleted by DSE.
|
; There is no dead store in this test. Make sure no store is deleted by DSE.
|
||||||
; Test case related to bug report PR52774.
|
; Test case related to bug report PR52774.
|
||||||
|
|
||||||
define %struct.ilist* @test() {
|
define ptr @test() {
|
||||||
; CHECK-LABEL: @test(
|
; CHECK-LABEL: @test(
|
||||||
; CHECK-NEXT: br label [[LOOP:%.*]]
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||||||
; CHECK: loop:
|
; CHECK: loop:
|
||||||
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
|
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
|
||||||
; CHECK-NEXT: [[LIST_NEXT:%.*]] = phi %struct.ilist* [ null, [[TMP0]] ], [ [[LIST_NEW_ILIST_PTR:%.*]], [[LOOP]] ]
|
; CHECK-NEXT: [[LIST_NEXT:%.*]] = phi ptr [ null, [[TMP0]] ], [ [[LIST_NEW_I8_PTR:%.*]], [[LOOP]] ]
|
||||||
; CHECK-NEXT: [[LIST_NEW_I8_PTR:%.*]] = tail call align 8 dereferenceable_or_null(8) i8* @malloc(i32 8)
|
; CHECK-NEXT: [[LIST_NEW_I8_PTR]] = tail call align 8 dereferenceable_or_null(8) ptr @malloc(i32 8)
|
||||||
; CHECK-NEXT: [[LIST_NEW_ILIST_PTR]] = bitcast i8* [[LIST_NEW_I8_PTR]] to %struct.ilist*
|
; CHECK-NEXT: store i32 42, ptr [[LIST_NEW_I8_PTR]], align 8
|
||||||
; CHECK-NEXT: [[GEP_NEW_VALUE:%.*]] = getelementptr inbounds [[STRUCT_ILIST:%.*]], %struct.ilist* [[LIST_NEW_ILIST_PTR]], i32 0, i32 0
|
; CHECK-NEXT: [[GEP_NEW_NEXT:%.*]] = getelementptr inbounds [[STRUCT_ILIST:%.*]], ptr [[LIST_NEW_I8_PTR]], i32 0, i32 1
|
||||||
; CHECK-NEXT: store i32 42, i32* [[GEP_NEW_VALUE]], align 8
|
; CHECK-NEXT: store ptr [[LIST_NEXT]], ptr [[GEP_NEW_NEXT]], align 4
|
||||||
; CHECK-NEXT: [[GEP_NEW_NEXT:%.*]] = getelementptr inbounds [[STRUCT_ILIST]], %struct.ilist* [[LIST_NEW_ILIST_PTR]], i32 0, i32 1
|
|
||||||
; CHECK-NEXT: store %struct.ilist* [[LIST_NEXT]], %struct.ilist** [[GEP_NEW_NEXT]], align 4
|
|
||||||
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
|
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
|
||||||
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[IV_NEXT]], 10
|
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[IV_NEXT]], 10
|
||||||
; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]]
|
; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: [[LIST_LAST_ILIST_PTR:%.*]] = bitcast i8* [[LIST_NEW_I8_PTR]] to %struct.ilist*
|
; CHECK-NEXT: [[GEP_LIST_LAST_NEXT:%.*]] = getelementptr inbounds [[STRUCT_ILIST]], ptr [[LIST_NEW_I8_PTR]], i32 0, i32 1
|
||||||
; CHECK-NEXT: [[GEP_LIST_LAST_NEXT:%.*]] = getelementptr inbounds [[STRUCT_ILIST]], %struct.ilist* [[LIST_LAST_ILIST_PTR]], i32 0, i32 1
|
; CHECK-NEXT: store ptr null, ptr [[GEP_LIST_LAST_NEXT]], align 4
|
||||||
; CHECK-NEXT: store %struct.ilist* null, %struct.ilist** [[GEP_LIST_LAST_NEXT]], align 4
|
; CHECK-NEXT: [[GEP_LIST_NEXT_NEXT:%.*]] = getelementptr inbounds [[STRUCT_ILIST]], ptr [[LIST_NEXT]], i32 0, i32 1
|
||||||
; CHECK-NEXT: [[GEP_LIST_NEXT_NEXT:%.*]] = getelementptr inbounds [[STRUCT_ILIST]], %struct.ilist* [[LIST_NEXT]], i32 0, i32 1
|
; CHECK-NEXT: [[LOADED_PTR:%.*]] = load ptr, ptr [[GEP_LIST_NEXT_NEXT]], align 4
|
||||||
; CHECK-NEXT: [[LOADED_PTR:%.*]] = load %struct.ilist*, %struct.ilist** [[GEP_LIST_NEXT_NEXT]], align 4
|
; CHECK-NEXT: ret ptr [[LOADED_PTR]]
|
||||||
; CHECK-NEXT: ret %struct.ilist* [[LOADED_PTR]]
|
|
||||||
;
|
;
|
||||||
br label %loop
|
br label %loop
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
%iv = phi i32 [ 0, %0 ], [ %iv.next, %loop ]
|
%iv = phi i32 [ 0, %0 ], [ %iv.next, %loop ]
|
||||||
%list.next = phi %struct.ilist* [ null, %0 ], [ %list.new.ilist.ptr, %loop ]
|
%list.next = phi ptr [ null, %0 ], [ %list.new.i8.ptr, %loop ]
|
||||||
%list.new.i8.ptr = tail call align 8 dereferenceable_or_null(8) i8* @malloc(i32 8)
|
%list.new.i8.ptr = tail call align 8 dereferenceable_or_null(8) ptr @malloc(i32 8)
|
||||||
%list.new.ilist.ptr = bitcast i8* %list.new.i8.ptr to %struct.ilist*
|
store i32 42, ptr %list.new.i8.ptr, align 8
|
||||||
%gep.new.value = getelementptr inbounds %struct.ilist, %struct.ilist* %list.new.ilist.ptr, i32 0, i32 0
|
%gep.new.next = getelementptr inbounds %struct.ilist, ptr %list.new.i8.ptr, i32 0, i32 1
|
||||||
store i32 42, i32* %gep.new.value, align 8
|
store ptr %list.next, ptr %gep.new.next, align 4
|
||||||
%gep.new.next = getelementptr inbounds %struct.ilist, %struct.ilist* %list.new.ilist.ptr, i32 0, i32 1
|
|
||||||
store %struct.ilist* %list.next, %struct.ilist** %gep.new.next, align 4
|
|
||||||
%iv.next = add nuw nsw i32 %iv, 1
|
%iv.next = add nuw nsw i32 %iv, 1
|
||||||
%cond = icmp eq i32 %iv.next, 10
|
%cond = icmp eq i32 %iv.next, 10
|
||||||
br i1 %cond, label %exit, label %loop
|
br i1 %cond, label %exit, label %loop
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
%list.last.ilist.ptr = bitcast i8* %list.new.i8.ptr to %struct.ilist*
|
%gep.list.last.next = getelementptr inbounds %struct.ilist, ptr %list.new.i8.ptr, i32 0, i32 1
|
||||||
%gep.list.last.next = getelementptr inbounds %struct.ilist, %struct.ilist* %list.last.ilist.ptr, i32 0, i32 1
|
store ptr null, ptr %gep.list.last.next, align 4
|
||||||
store %struct.ilist* null, %struct.ilist** %gep.list.last.next, align 4
|
%gep.list.next.next = getelementptr inbounds %struct.ilist, ptr %list.next, i32 0, i32 1
|
||||||
%gep.list.next.next = getelementptr inbounds %struct.ilist, %struct.ilist* %list.next, i32 0, i32 1
|
%loaded_ptr = load ptr, ptr %gep.list.next.next, align 4
|
||||||
%loaded_ptr = load %struct.ilist*, %struct.ilist** %gep.list.next.next, align 4
|
ret ptr %loaded_ptr ; use loaded pointer
|
||||||
ret %struct.ilist* %loaded_ptr ; use loaded pointer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
; Function Attrs: inaccessiblememonly nounwind
|
; Function Attrs: inaccessiblememonly nounwind
|
||||||
declare noalias noundef align 8 i8* @malloc(i32 noundef) local_unnamed_addr #0
|
declare noalias noundef align 8 ptr @malloc(i32 noundef) local_unnamed_addr #0
|
||||||
|
|
||||||
attributes #0 = { inaccessiblememonly nounwind}
|
attributes #0 = { inaccessiblememonly nounwind}
|
||||||
|
|
|
@ -7,14 +7,14 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
|
||||||
|
|
||||||
@a = external global [32 x i8], align 16
|
@a = external global [32 x i8], align 16
|
||||||
|
|
||||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg)
|
declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg)
|
||||||
|
|
||||||
; Test case for PR16520. The store in %if.then is redundant, because the same value
|
; Test case for PR16520. The store in %if.then is redundant, because the same value
|
||||||
; has been stored earlier to the same location.
|
; has been stored earlier to the same location.
|
||||||
define void @test1_pr16520(i1 %b, i8* nocapture %r) {
|
define void @test1_pr16520(i1 %b, ptr nocapture %r) {
|
||||||
; CHECK-LABEL: @test1_pr16520(
|
; CHECK-LABEL: @test1_pr16520(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i8 1, i8* [[R:%.*]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[R:%.*]], align 1
|
||||||
; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
||||||
; CHECK: if.then:
|
; CHECK: if.then:
|
||||||
; CHECK-NEXT: tail call void @fn_mayread_or_clobber()
|
; CHECK-NEXT: tail call void @fn_mayread_or_clobber()
|
||||||
|
@ -26,11 +26,11 @@ define void @test1_pr16520(i1 %b, i8* nocapture %r) {
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i8 1, i8* %r, align 1
|
store i8 1, ptr %r, align 1
|
||||||
br i1 %b, label %if.then, label %if.else
|
br i1 %b, label %if.then, label %if.else
|
||||||
|
|
||||||
if.then: ; preds = %entry
|
if.then: ; preds = %entry
|
||||||
store i8 1, i8* %r, align 1
|
store i8 1, ptr %r, align 1
|
||||||
tail call void @fn_mayread_or_clobber()
|
tail call void @fn_mayread_or_clobber()
|
||||||
br label %if.end
|
br label %if.end
|
||||||
|
|
||||||
|
@ -45,10 +45,10 @@ if.end: ; preds = %if.else, %if.then
|
||||||
declare void @fn_mayread_or_clobber()
|
declare void @fn_mayread_or_clobber()
|
||||||
declare void @fn_readonly() readonly
|
declare void @fn_readonly() readonly
|
||||||
|
|
||||||
define void @test2(i1 %b, i8* nocapture %r) {
|
define void @test2(i1 %b, ptr nocapture %r) {
|
||||||
; CHECK-LABEL: @test2(
|
; CHECK-LABEL: @test2(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i8 1, i8* [[R:%.*]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[R:%.*]], align 1
|
||||||
; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
||||||
; CHECK: if.then:
|
; CHECK: if.then:
|
||||||
; CHECK-NEXT: tail call void @fn_readonly()
|
; CHECK-NEXT: tail call void @fn_readonly()
|
||||||
|
@ -60,7 +60,7 @@ define void @test2(i1 %b, i8* nocapture %r) {
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i8 1, i8* %r, align 1
|
store i8 1, ptr %r, align 1
|
||||||
br i1 %b, label %if.then, label %if.else
|
br i1 %b, label %if.then, label %if.else
|
||||||
|
|
||||||
if.then: ; preds = %entry
|
if.then: ; preds = %entry
|
||||||
|
@ -72,15 +72,15 @@ if.else: ; preds = %entry
|
||||||
br label %if.end
|
br label %if.end
|
||||||
|
|
||||||
if.end: ; preds = %if.else, %if.then
|
if.end: ; preds = %if.else, %if.then
|
||||||
store i8 1, i8* %r, align 1
|
store i8 1, ptr %r, align 1
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Make sure volatile stores are not removed.
|
; Make sure volatile stores are not removed.
|
||||||
define void @test2_volatile(i1 %b, i8* nocapture %r) {
|
define void @test2_volatile(i1 %b, ptr nocapture %r) {
|
||||||
; CHECK-LABEL: @test2_volatile(
|
; CHECK-LABEL: @test2_volatile(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store volatile i8 1, i8* [[R:%.*]], align 1
|
; CHECK-NEXT: store volatile i8 1, ptr [[R:%.*]], align 1
|
||||||
; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
||||||
; CHECK: if.then:
|
; CHECK: if.then:
|
||||||
; CHECK-NEXT: tail call void @fn_readonly()
|
; CHECK-NEXT: tail call void @fn_readonly()
|
||||||
|
@ -89,11 +89,11 @@ define void @test2_volatile(i1 %b, i8* nocapture %r) {
|
||||||
; CHECK-NEXT: tail call void @fn_readonly()
|
; CHECK-NEXT: tail call void @fn_readonly()
|
||||||
; CHECK-NEXT: br label [[IF_END]]
|
; CHECK-NEXT: br label [[IF_END]]
|
||||||
; CHECK: if.end:
|
; CHECK: if.end:
|
||||||
; CHECK-NEXT: store volatile i8 1, i8* [[R]], align 1
|
; CHECK-NEXT: store volatile i8 1, ptr [[R]], align 1
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store volatile i8 1, i8* %r, align 1
|
store volatile i8 1, ptr %r, align 1
|
||||||
br i1 %b, label %if.then, label %if.else
|
br i1 %b, label %if.then, label %if.else
|
||||||
|
|
||||||
if.then: ; preds = %entry
|
if.then: ; preds = %entry
|
||||||
|
@ -105,14 +105,14 @@ if.else: ; preds = %entry
|
||||||
br label %if.end
|
br label %if.end
|
||||||
|
|
||||||
if.end: ; preds = %if.else, %if.then
|
if.end: ; preds = %if.else, %if.then
|
||||||
store volatile i8 1, i8* %r, align 1
|
store volatile i8 1, ptr %r, align 1
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test3(i1 %b, i8* nocapture %r) {
|
define void @test3(i1 %b, ptr nocapture %r) {
|
||||||
; CHECK-LABEL: @test3(
|
; CHECK-LABEL: @test3(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i8 1, i8* [[R:%.*]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[R:%.*]], align 1
|
||||||
; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
||||||
; CHECK: if.then:
|
; CHECK: if.then:
|
||||||
; CHECK-NEXT: tail call void @fn_mayread_or_clobber()
|
; CHECK-NEXT: tail call void @fn_mayread_or_clobber()
|
||||||
|
@ -121,11 +121,11 @@ define void @test3(i1 %b, i8* nocapture %r) {
|
||||||
; CHECK-NEXT: tail call void @fn_readonly()
|
; CHECK-NEXT: tail call void @fn_readonly()
|
||||||
; CHECK-NEXT: br label [[IF_END]]
|
; CHECK-NEXT: br label [[IF_END]]
|
||||||
; CHECK: if.end:
|
; CHECK: if.end:
|
||||||
; CHECK-NEXT: store i8 1, i8* [[R]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[R]], align 1
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i8 1, i8* %r, align 1
|
store i8 1, ptr %r, align 1
|
||||||
br i1 %b, label %if.then, label %if.else
|
br i1 %b, label %if.then, label %if.else
|
||||||
|
|
||||||
if.then: ; preds = %entry
|
if.then: ; preds = %entry
|
||||||
|
@ -137,14 +137,14 @@ if.else: ; preds = %entry
|
||||||
br label %if.end
|
br label %if.end
|
||||||
|
|
||||||
if.end: ; preds = %if.else, %if.then
|
if.end: ; preds = %if.else, %if.then
|
||||||
store i8 1, i8* %r, align 1
|
store i8 1, ptr %r, align 1
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test4(i1 %b, i8* nocapture %r) {
|
define void @test4(i1 %b, ptr nocapture %r) {
|
||||||
; CHECK-LABEL: @test4(
|
; CHECK-LABEL: @test4(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i8 1, i8* [[R:%.*]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[R:%.*]], align 1
|
||||||
; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
||||||
; CHECK: if.then:
|
; CHECK: if.then:
|
||||||
; CHECK-NEXT: tail call void @fn_readonly()
|
; CHECK-NEXT: tail call void @fn_readonly()
|
||||||
|
@ -153,11 +153,11 @@ define void @test4(i1 %b, i8* nocapture %r) {
|
||||||
; CHECK-NEXT: tail call void @fn_mayread_or_clobber()
|
; CHECK-NEXT: tail call void @fn_mayread_or_clobber()
|
||||||
; CHECK-NEXT: br label [[IF_END]]
|
; CHECK-NEXT: br label [[IF_END]]
|
||||||
; CHECK: if.end:
|
; CHECK: if.end:
|
||||||
; CHECK-NEXT: store i8 1, i8* [[R]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[R]], align 1
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i8 1, i8* %r, align 1
|
store i8 1, ptr %r, align 1
|
||||||
br i1 %b, label %if.then, label %if.else
|
br i1 %b, label %if.then, label %if.else
|
||||||
|
|
||||||
if.then: ; preds = %entry
|
if.then: ; preds = %entry
|
||||||
|
@ -169,14 +169,14 @@ if.else: ; preds = %entry
|
||||||
br label %if.end
|
br label %if.end
|
||||||
|
|
||||||
if.end: ; preds = %if.else, %if.then
|
if.end: ; preds = %if.else, %if.then
|
||||||
store i8 1, i8* %r, align 1
|
store i8 1, ptr %r, align 1
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test5(i1 %b, i8* nocapture %r) {
|
define void @test5(i1 %b, ptr nocapture %r) {
|
||||||
; CHECK-LABEL: @test5(
|
; CHECK-LABEL: @test5(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i8 1, i8* [[R:%.*]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[R:%.*]], align 1
|
||||||
; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
||||||
; CHECK: if.then:
|
; CHECK: if.then:
|
||||||
; CHECK-NEXT: tail call void @fn_readonly()
|
; CHECK-NEXT: tail call void @fn_readonly()
|
||||||
|
@ -185,11 +185,11 @@ define void @test5(i1 %b, i8* nocapture %r) {
|
||||||
; CHECK-NEXT: tail call void @fn_mayread_or_clobber()
|
; CHECK-NEXT: tail call void @fn_mayread_or_clobber()
|
||||||
; CHECK-NEXT: br label [[IF_END]]
|
; CHECK-NEXT: br label [[IF_END]]
|
||||||
; CHECK: if.end:
|
; CHECK: if.end:
|
||||||
; CHECK-NEXT: store i8 1, i8* [[R]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[R]], align 1
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
store i8 1, i8* %r, align 1
|
store i8 1, ptr %r, align 1
|
||||||
br i1 %b, label %if.then, label %if.else
|
br i1 %b, label %if.then, label %if.else
|
||||||
|
|
||||||
if.then: ; preds = %entry
|
if.then: ; preds = %entry
|
||||||
|
@ -201,49 +201,49 @@ if.else: ; preds = %entry
|
||||||
br label %if.end
|
br label %if.end
|
||||||
|
|
||||||
if.end: ; preds = %if.else, %if.then
|
if.end: ; preds = %if.else, %if.then
|
||||||
store i8 1, i8* %r, align 1
|
store i8 1, ptr %r, align 1
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i1 @cond() readnone
|
declare i1 @cond() readnone
|
||||||
|
|
||||||
define void @test6(i32* noalias %P) {
|
define void @test6(ptr noalias %P) {
|
||||||
; CHECK-LABEL: @test6(
|
; CHECK-LABEL: @test6(
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: br label [[FOR_HEADER:%.*]]
|
; CHECK-NEXT: br label [[FOR_HEADER:%.*]]
|
||||||
; CHECK: for.header:
|
; CHECK: for.header:
|
||||||
; CHECK-NEXT: store i32 1, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
|
; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
|
||||||
; CHECK-NEXT: br i1 [[C1]], label [[FOR_BODY:%.*]], label [[END:%.*]]
|
; CHECK-NEXT: br i1 [[C1]], label [[FOR_BODY:%.*]], label [[END:%.*]]
|
||||||
; CHECK: for.body:
|
; CHECK: for.body:
|
||||||
; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[P]], align 4
|
; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: br label [[FOR_HEADER]]
|
; CHECK-NEXT: br label [[FOR_HEADER]]
|
||||||
; CHECK: end:
|
; CHECK: end:
|
||||||
; CHECK-NEXT: store i32 3, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 3, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
br label %for.header
|
br label %for.header
|
||||||
|
|
||||||
for.header:
|
for.header:
|
||||||
store i32 1, i32* %P, align 4
|
store i32 1, ptr %P, align 4
|
||||||
%c1 = call i1 @cond()
|
%c1 = call i1 @cond()
|
||||||
br i1 %c1, label %for.body, label %end
|
br i1 %c1, label %for.body, label %end
|
||||||
|
|
||||||
for.body:
|
for.body:
|
||||||
store i32 1, i32* %P, align 4
|
store i32 1, ptr %P, align 4
|
||||||
%lv = load i32, i32* %P
|
%lv = load i32, ptr %P
|
||||||
br label %for.header
|
br label %for.header
|
||||||
|
|
||||||
end:
|
end:
|
||||||
store i32 3, i32* %P, align 4
|
store i32 3, ptr %P, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Make sure the store in %bb3 can be eliminated in the presences of early returns.
|
; Make sure the store in %bb3 can be eliminated in the presences of early returns.
|
||||||
define void @test7(i32* noalias %P) {
|
define void @test7(ptr noalias %P) {
|
||||||
; CHECK-LABEL: @test7(
|
; CHECK-LABEL: @test7(
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
|
@ -252,21 +252,21 @@ define void @test7(i32* noalias %P) {
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
bb2:
|
bb2:
|
||||||
ret void
|
ret void
|
||||||
bb3:
|
bb3:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Make sure the store in %bb3 won't be eliminated because it may be clobbered before.
|
; Make sure the store in %bb3 won't be eliminated because it may be clobbered before.
|
||||||
define void @test8(i32* %P) {
|
define void @test8(ptr %P) {
|
||||||
; CHECK-LABEL: @test8(
|
; CHECK-LABEL: @test8(
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: call void @fn_mayread_or_clobber()
|
; CHECK-NEXT: call void @fn_mayread_or_clobber()
|
||||||
|
@ -274,10 +274,10 @@ define void @test8(i32* %P) {
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
call void @fn_mayread_or_clobber()
|
call void @fn_mayread_or_clobber()
|
||||||
|
@ -285,15 +285,15 @@ bb1:
|
||||||
bb2:
|
bb2:
|
||||||
ret void
|
ret void
|
||||||
bb3:
|
bb3:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Make sure the store in %bb3 will be eliminated because only the early exit path
|
; Make sure the store in %bb3 will be eliminated because only the early exit path
|
||||||
; may be clobbered.
|
; may be clobbered.
|
||||||
define void @test9(i32* noalias %P) {
|
define void @test9(ptr noalias %P) {
|
||||||
; CHECK-LABEL: @test9(
|
; CHECK-LABEL: @test9(
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
|
@ -303,7 +303,7 @@ define void @test9(i32* noalias %P) {
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 true, label %bb1, label %bb2
|
br i1 true, label %bb1, label %bb2
|
||||||
bb1:
|
bb1:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
|
@ -311,64 +311,63 @@ bb2:
|
||||||
call void @fn_mayread_or_clobber()
|
call void @fn_mayread_or_clobber()
|
||||||
ret void
|
ret void
|
||||||
bb3:
|
bb3:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; The store in bb3 can be eliminated, because the store in bb1 cannot alias it.
|
; The store in bb3 can be eliminated, because the store in bb1 cannot alias it.
|
||||||
define void @test10(i32* noalias %P, i32* %Q, i1 %c) {
|
define void @test10(ptr noalias %P, ptr %Q, i1 %c) {
|
||||||
; UNOPT-LABEL: @test10(
|
; UNOPT-LABEL: @test10(
|
||||||
; UNOPT-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; UNOPT-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; UNOPT-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; UNOPT-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; UNOPT: bb1:
|
; UNOPT: bb1:
|
||||||
; UNOPT-NEXT: store i32 10, i32* [[Q:%.*]], align 4
|
; UNOPT-NEXT: store i32 10, ptr [[Q:%.*]], align 4
|
||||||
; UNOPT-NEXT: br label [[BB3:%.*]]
|
; UNOPT-NEXT: br label [[BB3:%.*]]
|
||||||
; UNOPT: bb2:
|
; UNOPT: bb2:
|
||||||
; UNOPT-NEXT: ret void
|
; UNOPT-NEXT: ret void
|
||||||
; UNOPT: bb3:
|
; UNOPT: bb3:
|
||||||
; UNOPT-NEXT: store i32 0, i32* [[P]], align 4
|
; UNOPT-NEXT: store i32 0, ptr [[P]], align 4
|
||||||
; UNOPT-NEXT: ret void
|
; UNOPT-NEXT: ret void
|
||||||
;
|
;
|
||||||
; OPT-LABEL: @test10(
|
; OPT-LABEL: @test10(
|
||||||
; OPT-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; OPT-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; OPT-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; OPT-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; OPT: bb1:
|
; OPT: bb1:
|
||||||
; OPT-NEXT: store i32 10, i32* [[Q:%.*]], align 4
|
; OPT-NEXT: store i32 10, ptr [[Q:%.*]], align 4
|
||||||
; OPT-NEXT: br label [[BB3:%.*]]
|
; OPT-NEXT: br label [[BB3:%.*]]
|
||||||
; OPT: bb2:
|
; OPT: bb2:
|
||||||
; OPT-NEXT: ret void
|
; OPT-NEXT: ret void
|
||||||
; OPT: bb3:
|
; OPT: bb3:
|
||||||
; OPT-NEXT: ret void
|
; OPT-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 %c, label %bb1, label %bb2
|
br i1 %c, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
store i32 10, i32* %Q
|
store i32 10, ptr %Q
|
||||||
br label %bb3
|
br label %bb3
|
||||||
|
|
||||||
bb2:
|
bb2:
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test11_smaller_later_store(i32* noalias %P, i32* %Q, i1 %c) {
|
define void @test11_smaller_later_store(ptr noalias %P, ptr %Q, i1 %c) {
|
||||||
; CHECK-LABEL: @test11_smaller_later_store(
|
; CHECK-LABEL: @test11_smaller_later_store(
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: [[BC:%.*]] = bitcast i32* [[P]] to i8*
|
; CHECK-NEXT: store i8 0, ptr [[P]], align 1
|
||||||
; CHECK-NEXT: store i8 0, i8* [[BC]], align 1
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
br i1 %c, label %bb1, label %bb2
|
br i1 %c, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
|
@ -378,26 +377,23 @@ bb2:
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
%bc = bitcast i32* %P to i8*
|
store i8 0, ptr %P
|
||||||
store i8 0, i8* %bc
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test11_smaller_earlier_store(i32* noalias %P, i32* %Q, i1 %c) {
|
define void @test11_smaller_earlier_store(ptr noalias %P, ptr %Q, i1 %c) {
|
||||||
; CHECK-LABEL: @test11_smaller_earlier_store(
|
; CHECK-LABEL: @test11_smaller_earlier_store(
|
||||||
; CHECK-NEXT: [[BC:%.*]] = bitcast i32* [[P:%.*]] to i8*
|
; CHECK-NEXT: store i8 0, ptr [[P:%.*]], align 1
|
||||||
; CHECK-NEXT: store i8 0, i8* [[BC]], align 1
|
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
|
||||||
; CHECK: bb1:
|
; CHECK: bb1:
|
||||||
; CHECK-NEXT: br label [[BB3:%.*]]
|
; CHECK-NEXT: br label [[BB3:%.*]]
|
||||||
; CHECK: bb2:
|
; CHECK: bb2:
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
; CHECK: bb3:
|
; CHECK: bb3:
|
||||||
; CHECK-NEXT: store i32 0, i32* [[P]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%bc = bitcast i32* %P to i8*
|
store i8 0, ptr %P
|
||||||
store i8 0, i8* %bc
|
|
||||||
br i1 %c, label %bb1, label %bb2
|
br i1 %c, label %bb1, label %bb2
|
||||||
|
|
||||||
bb1:
|
bb1:
|
||||||
|
@ -407,268 +403,254 @@ bb2:
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
bb3:
|
bb3:
|
||||||
store i32 0, i32* %P
|
store i32 0, ptr %P
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #1
|
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #1
|
||||||
|
|
||||||
define void @test12_memset_simple(i8* %ptr) {
|
define void @test12_memset_simple(ptr %ptr) {
|
||||||
; CHECK-LABEL: @test12_memset_simple(
|
; CHECK-LABEL: @test12_memset_simple(
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[PTR:%.*]], i8 0, i64 10, i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[PTR:%.*]], i8 0, i64 10, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 10, i1 false)
|
call void @llvm.memset.p0.i64(ptr %ptr, i8 0, i64 10, i1 false)
|
||||||
%ptr.5 = getelementptr i8, i8* %ptr, i64 4
|
%ptr.5 = getelementptr i8, ptr %ptr, i64 4
|
||||||
store i8 0, i8* %ptr.5
|
store i8 0, ptr %ptr.5
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test12_memset_other_store_in_between(i8* %ptr) {
|
define void @test12_memset_other_store_in_between(ptr %ptr) {
|
||||||
; UNOPT-LABEL: @test12_memset_other_store_in_between(
|
; UNOPT-LABEL: @test12_memset_other_store_in_between(
|
||||||
; UNOPT-NEXT: call void @llvm.memset.p0i8.i64(i8* [[PTR:%.*]], i8 0, i64 10, i1 false)
|
; UNOPT-NEXT: call void @llvm.memset.p0.i64(ptr [[PTR:%.*]], i8 0, i64 10, i1 false)
|
||||||
; UNOPT-NEXT: [[PTR_4:%.*]] = getelementptr i8, i8* [[PTR]], i64 4
|
; UNOPT-NEXT: [[PTR_4:%.*]] = getelementptr i8, ptr [[PTR]], i64 4
|
||||||
; UNOPT-NEXT: store i8 8, i8* [[PTR_4]], align 1
|
; UNOPT-NEXT: store i8 8, ptr [[PTR_4]], align 1
|
||||||
; UNOPT-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 5
|
; UNOPT-NEXT: [[PTR_5:%.*]] = getelementptr i8, ptr [[PTR]], i64 5
|
||||||
; UNOPT-NEXT: store i8 0, i8* [[PTR_5]], align 1
|
; UNOPT-NEXT: store i8 0, ptr [[PTR_5]], align 1
|
||||||
; UNOPT-NEXT: ret void
|
; UNOPT-NEXT: ret void
|
||||||
;
|
;
|
||||||
; OPT-LABEL: @test12_memset_other_store_in_between(
|
; OPT-LABEL: @test12_memset_other_store_in_between(
|
||||||
; OPT-NEXT: call void @llvm.memset.p0i8.i64(i8* [[PTR:%.*]], i8 0, i64 10, i1 false)
|
; OPT-NEXT: call void @llvm.memset.p0.i64(ptr [[PTR:%.*]], i8 0, i64 10, i1 false)
|
||||||
; OPT-NEXT: [[PTR_4:%.*]] = getelementptr i8, i8* [[PTR]], i64 4
|
; OPT-NEXT: [[PTR_4:%.*]] = getelementptr i8, ptr [[PTR]], i64 4
|
||||||
; OPT-NEXT: store i8 8, i8* [[PTR_4]], align 1
|
; OPT-NEXT: store i8 8, ptr [[PTR_4]], align 1
|
||||||
; OPT-NEXT: ret void
|
; OPT-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 10, i1 false)
|
call void @llvm.memset.p0.i64(ptr %ptr, i8 0, i64 10, i1 false)
|
||||||
%ptr.4 = getelementptr i8, i8* %ptr, i64 4
|
%ptr.4 = getelementptr i8, ptr %ptr, i64 4
|
||||||
store i8 8, i8* %ptr.4
|
store i8 8, ptr %ptr.4
|
||||||
%ptr.5 = getelementptr i8, i8* %ptr, i64 5
|
%ptr.5 = getelementptr i8, ptr %ptr, i64 5
|
||||||
store i8 0, i8* %ptr.5
|
store i8 0, ptr %ptr.5
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i8* @__memset_chk(i8* writeonly, i32, i64, i64) argmemonly writeonly nofree nounwind
|
declare ptr @__memset_chk(ptr writeonly, i32, i64, i64) argmemonly writeonly nofree nounwind
|
||||||
|
|
||||||
define void @test12_memset_chk_other_store_in_between(i8* %ptr) {
|
define void @test12_memset_chk_other_store_in_between(ptr %ptr) {
|
||||||
; CHECK-LABEL: @test12_memset_chk_other_store_in_between(
|
; CHECK-LABEL: @test12_memset_chk_other_store_in_between(
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__memset_chk(i8* [[PTR:%.*]], i32 0, i64 10, i64 -1)
|
; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @__memset_chk(ptr [[PTR:%.*]], i32 0, i64 10, i64 -1)
|
||||||
; CHECK-NEXT: [[PTR_4:%.*]] = getelementptr i8, i8* [[PTR]], i64 4
|
; CHECK-NEXT: [[PTR_4:%.*]] = getelementptr i8, ptr [[PTR]], i64 4
|
||||||
; CHECK-NEXT: store i8 8, i8* [[PTR_4]], align 1
|
; CHECK-NEXT: store i8 8, ptr [[PTR_4]], align 1
|
||||||
; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 5
|
; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, ptr [[PTR]], i64 5
|
||||||
; CHECK-NEXT: store i8 0, i8* [[PTR_5]], align 1
|
; CHECK-NEXT: store i8 0, ptr [[PTR_5]], align 1
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%call = tail call i8* @__memset_chk(i8* %ptr, i32 0, i64 10, i64 -1)
|
%call = tail call ptr @__memset_chk(ptr %ptr, i32 0, i64 10, i64 -1)
|
||||||
%ptr.4 = getelementptr i8, i8* %ptr, i64 4
|
%ptr.4 = getelementptr i8, ptr %ptr, i64 4
|
||||||
store i8 8, i8* %ptr.4
|
store i8 8, ptr %ptr.4
|
||||||
%ptr.5 = getelementptr i8, i8* %ptr, i64 5
|
%ptr.5 = getelementptr i8, ptr %ptr, i64 5
|
||||||
store i8 0, i8* %ptr.5
|
store i8 0, ptr %ptr.5
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @use(i8*)
|
declare void @use(ptr)
|
||||||
|
|
||||||
define void @test12_memset_chk_other_store_in_between_stack_obj_escape_after(i64 %n) {
|
define void @test12_memset_chk_other_store_in_between_stack_obj_escape_after(i64 %n) {
|
||||||
; CHECK-LABEL: @test12_memset_chk_other_store_in_between_stack_obj_escape_after(
|
; CHECK-LABEL: @test12_memset_chk_other_store_in_between_stack_obj_escape_after(
|
||||||
; CHECK-NEXT: [[OBJ:%.*]] = alloca [200 x i8], align 1
|
; CHECK-NEXT: [[OBJ:%.*]] = alloca [200 x i8], align 1
|
||||||
; CHECK-NEXT: [[PTR:%.*]] = bitcast [200 x i8]* [[OBJ]] to i8*
|
; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @__memset_chk(ptr [[OBJ]], i32 0, i64 10, i64 [[N:%.*]])
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__memset_chk(i8* [[PTR]], i32 0, i64 10, i64 [[N:%.*]])
|
; CHECK-NEXT: [[PTR_4:%.*]] = getelementptr i8, ptr [[OBJ]], i64 4
|
||||||
; CHECK-NEXT: [[PTR_4:%.*]] = getelementptr i8, i8* [[PTR]], i64 4
|
; CHECK-NEXT: store i8 8, ptr [[PTR_4]], align 1
|
||||||
; CHECK-NEXT: store i8 8, i8* [[PTR_4]], align 1
|
; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, ptr [[OBJ]], i64 5
|
||||||
; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 5
|
; CHECK-NEXT: store i8 0, ptr [[PTR_5]], align 1
|
||||||
; CHECK-NEXT: store i8 0, i8* [[PTR_5]], align 1
|
; CHECK-NEXT: call void @use(ptr [[OBJ]])
|
||||||
; CHECK-NEXT: call void @use(i8* [[PTR]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%obj = alloca [200 x i8]
|
%obj = alloca [200 x i8]
|
||||||
%ptr = bitcast [200 x i8]* %obj to i8*
|
%call = tail call ptr @__memset_chk(ptr %obj, i32 0, i64 10, i64 %n)
|
||||||
%call = tail call i8* @__memset_chk(i8* %ptr, i32 0, i64 10, i64 %n)
|
%ptr.4 = getelementptr i8, ptr %obj, i64 4
|
||||||
%ptr.4 = getelementptr i8, i8* %ptr, i64 4
|
store i8 8, ptr %ptr.4
|
||||||
store i8 8, i8* %ptr.4
|
%ptr.5 = getelementptr i8, ptr %obj, i64 5
|
||||||
%ptr.5 = getelementptr i8, i8* %ptr, i64 5
|
store i8 0, ptr %ptr.5
|
||||||
store i8 0, i8* %ptr.5
|
call void @use(ptr %obj)
|
||||||
call void @use(i8* %ptr)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test12_memset_chk_other_store_in_between_stack_obj_escape_before(i64 %n) {
|
define void @test12_memset_chk_other_store_in_between_stack_obj_escape_before(i64 %n) {
|
||||||
; CHECK-LABEL: @test12_memset_chk_other_store_in_between_stack_obj_escape_before(
|
; CHECK-LABEL: @test12_memset_chk_other_store_in_between_stack_obj_escape_before(
|
||||||
; CHECK-NEXT: [[OBJ:%.*]] = alloca [200 x i8], align 1
|
; CHECK-NEXT: [[OBJ:%.*]] = alloca [200 x i8], align 1
|
||||||
; CHECK-NEXT: [[PTR:%.*]] = bitcast [200 x i8]* [[OBJ]] to i8*
|
; CHECK-NEXT: call void @use(ptr [[OBJ]])
|
||||||
; CHECK-NEXT: call void @use(i8* [[PTR]])
|
; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @__memset_chk(ptr [[OBJ]], i32 0, i64 10, i64 [[N:%.*]])
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__memset_chk(i8* [[PTR]], i32 0, i64 10, i64 [[N:%.*]])
|
; CHECK-NEXT: [[PTR_4:%.*]] = getelementptr i8, ptr [[OBJ]], i64 4
|
||||||
; CHECK-NEXT: [[PTR_4:%.*]] = getelementptr i8, i8* [[PTR]], i64 4
|
; CHECK-NEXT: store i8 8, ptr [[PTR_4]], align 1
|
||||||
; CHECK-NEXT: store i8 8, i8* [[PTR_4]], align 1
|
; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, ptr [[OBJ]], i64 5
|
||||||
; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 5
|
; CHECK-NEXT: store i8 0, ptr [[PTR_5]], align 1
|
||||||
; CHECK-NEXT: store i8 0, i8* [[PTR_5]], align 1
|
; CHECK-NEXT: [[PTR_10:%.*]] = getelementptr i8, ptr [[OBJ]], i64 10
|
||||||
; CHECK-NEXT: [[PTR_10:%.*]] = getelementptr i8, i8* [[PTR]], i64 10
|
; CHECK-NEXT: store i8 0, ptr [[PTR_10]], align 1
|
||||||
; CHECK-NEXT: store i8 0, i8* [[PTR_10]], align 1
|
; CHECK-NEXT: call void @use(ptr [[OBJ]])
|
||||||
; CHECK-NEXT: call void @use(i8* [[PTR]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%obj = alloca [200 x i8]
|
%obj = alloca [200 x i8]
|
||||||
%ptr = bitcast [200 x i8]* %obj to i8*
|
call void @use(ptr %obj)
|
||||||
call void @use(i8* %ptr)
|
%call = tail call ptr @__memset_chk(ptr %obj, i32 0, i64 10, i64 %n)
|
||||||
%call = tail call i8* @__memset_chk(i8* %ptr, i32 0, i64 10, i64 %n)
|
%ptr.4 = getelementptr i8, ptr %obj, i64 4
|
||||||
%ptr.4 = getelementptr i8, i8* %ptr, i64 4
|
store i8 8, ptr %ptr.4
|
||||||
store i8 8, i8* %ptr.4
|
%ptr.5 = getelementptr i8, ptr %obj, i64 5
|
||||||
%ptr.5 = getelementptr i8, i8* %ptr, i64 5
|
store i8 0, ptr %ptr.5
|
||||||
store i8 0, i8* %ptr.5
|
%ptr.10 = getelementptr i8, ptr %obj, i64 10
|
||||||
%ptr.10 = getelementptr i8, i8* %ptr, i64 10
|
store i8 0, ptr %ptr.10
|
||||||
store i8 0, i8* %ptr.10
|
call void @use(ptr %obj)
|
||||||
call void @use(i8* %ptr)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test12_memset_other_store_in_between_partial_overlap(i8* %ptr) {
|
define void @test12_memset_other_store_in_between_partial_overlap(ptr %ptr) {
|
||||||
; CHECK-LABEL: @test12_memset_other_store_in_between_partial_overlap(
|
; CHECK-LABEL: @test12_memset_other_store_in_between_partial_overlap(
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[PTR:%.*]], i8 0, i64 10, i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[PTR:%.*]], i8 0, i64 10, i1 false)
|
||||||
; CHECK-NEXT: [[PTR_4:%.*]] = getelementptr i8, i8* [[PTR]], i64 4
|
; CHECK-NEXT: [[PTR_4:%.*]] = getelementptr i8, ptr [[PTR]], i64 4
|
||||||
; CHECK-NEXT: [[BC_4:%.*]] = bitcast i8* [[PTR_4]] to i16*
|
; CHECK-NEXT: store i16 8, ptr [[PTR_4]], align 2
|
||||||
; CHECK-NEXT: store i16 8, i16* [[BC_4]], align 2
|
; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, ptr [[PTR]], i64 5
|
||||||
; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 5
|
; CHECK-NEXT: store i16 0, ptr [[PTR_5]], align 2
|
||||||
; CHECK-NEXT: [[BC_5:%.*]] = bitcast i8* [[PTR_5]] to i16*
|
|
||||||
; CHECK-NEXT: store i16 0, i16* [[BC_5]], align 2
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 10, i1 false)
|
call void @llvm.memset.p0.i64(ptr %ptr, i8 0, i64 10, i1 false)
|
||||||
%ptr.4 = getelementptr i8, i8* %ptr, i64 4
|
%ptr.4 = getelementptr i8, ptr %ptr, i64 4
|
||||||
%bc.4 = bitcast i8* %ptr.4 to i16*
|
store i16 8, ptr %ptr.4
|
||||||
store i16 8, i16* %bc.4
|
%ptr.5 = getelementptr i8, ptr %ptr, i64 5
|
||||||
%ptr.5 = getelementptr i8, i8* %ptr, i64 5
|
store i16 0, ptr %ptr.5
|
||||||
%bc.5 = bitcast i8* %ptr.5 to i16*
|
|
||||||
store i16 0, i16* %bc.5
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test12_memset_later_store_exceeds_memset(i8* %ptr) {
|
define void @test12_memset_later_store_exceeds_memset(ptr %ptr) {
|
||||||
; CHECK-LABEL: @test12_memset_later_store_exceeds_memset(
|
; CHECK-LABEL: @test12_memset_later_store_exceeds_memset(
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[PTR:%.*]], i8 0, i64 8, i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[PTR:%.*]], i8 0, i64 8, i1 false)
|
||||||
; CHECK-NEXT: [[PTR_4:%.*]] = getelementptr i8, i8* [[PTR]], i64 4
|
; CHECK-NEXT: [[PTR_4:%.*]] = getelementptr i8, ptr [[PTR]], i64 4
|
||||||
; CHECK-NEXT: store i8 8, i8* [[PTR_4]], align 1
|
; CHECK-NEXT: store i8 8, ptr [[PTR_4]], align 1
|
||||||
; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 8
|
; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, ptr [[PTR]], i64 8
|
||||||
; CHECK-NEXT: [[BC:%.*]] = bitcast i8* [[PTR_5]] to i64*
|
; CHECK-NEXT: store i64 0, ptr [[PTR_5]], align 8
|
||||||
; CHECK-NEXT: store i64 0, i64* [[BC]], align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 10, i1 false)
|
call void @llvm.memset.p0.i64(ptr %ptr, i8 0, i64 10, i1 false)
|
||||||
%ptr.4 = getelementptr i8, i8* %ptr, i64 4
|
%ptr.4 = getelementptr i8, ptr %ptr, i64 4
|
||||||
store i8 8, i8* %ptr.4
|
store i8 8, ptr %ptr.4
|
||||||
%ptr.5 = getelementptr i8, i8* %ptr, i64 8
|
%ptr.5 = getelementptr i8, ptr %ptr, i64 8
|
||||||
%bc = bitcast i8* %ptr.5 to i64*
|
store i64 0, ptr %ptr.5
|
||||||
store i64 0, i64* %bc
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test12_memset_later_store_before_memset(i8* %ptr) {
|
define void @test12_memset_later_store_before_memset(ptr %ptr) {
|
||||||
; CHECK-LABEL: @test12_memset_later_store_before_memset(
|
; CHECK-LABEL: @test12_memset_later_store_before_memset(
|
||||||
; CHECK-NEXT: [[PTR_1:%.*]] = getelementptr i8, i8* [[PTR:%.*]], i64 1
|
; CHECK-NEXT: [[PTR_1:%.*]] = getelementptr i8, ptr [[PTR:%.*]], i64 1
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[PTR_1]], i64 7
|
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[PTR_1]], i64 7
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP1]], i8 0, i64 3, i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP1]], i8 0, i64 3, i1 false)
|
||||||
; CHECK-NEXT: [[BC:%.*]] = bitcast i8* [[PTR]] to i64*
|
; CHECK-NEXT: store i64 0, ptr [[PTR]], align 8
|
||||||
; CHECK-NEXT: store i64 0, i64* [[BC]], align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%ptr.1 = getelementptr i8, i8* %ptr, i64 1
|
%ptr.1 = getelementptr i8, ptr %ptr, i64 1
|
||||||
call void @llvm.memset.p0i8.i64(i8* %ptr.1, i8 0, i64 10, i1 false)
|
call void @llvm.memset.p0.i64(ptr %ptr.1, i8 0, i64 10, i1 false)
|
||||||
%ptr.4 = getelementptr i8, i8* %ptr, i64 4
|
%ptr.4 = getelementptr i8, ptr %ptr, i64 4
|
||||||
store i8 8, i8* %ptr.4
|
store i8 8, ptr %ptr.4
|
||||||
%bc = bitcast i8* %ptr to i64*
|
store i64 0, ptr %ptr
|
||||||
store i64 0, i64* %bc
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; The memset will be shortened and the store will not be redundant afterwards.
|
; The memset will be shortened and the store will not be redundant afterwards.
|
||||||
; It cannot be eliminated.
|
; It cannot be eliminated.
|
||||||
define void @test13_memset_shortened(i64* %ptr) {
|
define void @test13_memset_shortened(ptr %ptr) {
|
||||||
; CHECK-LABEL: @test13_memset_shortened(
|
; CHECK-LABEL: @test13_memset_shortened(
|
||||||
; CHECK-NEXT: [[PTR_I8:%.*]] = bitcast i64* [[PTR:%.*]] to i8*
|
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 8
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[PTR_I8]], i64 8
|
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[TMP1]], i8 0, i64 16, i1 false)
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP1]], i8 0, i64 16, i1 false)
|
; CHECK-NEXT: store i64 0, ptr [[PTR]], align 8
|
||||||
; CHECK-NEXT: store i64 0, i64* [[PTR]], align 8
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%ptr.i8 = bitcast i64* %ptr to i8*
|
call void @llvm.memset.p0.i64(ptr %ptr, i8 0, i64 24, i1 false)
|
||||||
call void @llvm.memset.p0i8.i64(i8* %ptr.i8, i8 0, i64 24, i1 false)
|
store i64 0, ptr %ptr
|
||||||
store i64 0, i64* %ptr
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i8* @strcat(i8*, i8*) nounwind argmemonly
|
declare ptr @strcat(ptr, ptr) nounwind argmemonly
|
||||||
|
|
||||||
define void @test14_strcat(i8* noalias %P, i8* noalias %Q) {
|
define void @test14_strcat(ptr noalias %P, ptr noalias %Q) {
|
||||||
; CHECK-LABEL: @test14_strcat(
|
; CHECK-LABEL: @test14_strcat(
|
||||||
; CHECK-NEXT: [[CALL1:%.*]] = call i8* @strcat(i8* [[P:%.*]], i8* [[Q:%.*]])
|
; CHECK-NEXT: [[CALL1:%.*]] = call ptr @strcat(ptr [[P:%.*]], ptr [[Q:%.*]])
|
||||||
; CHECK-NEXT: [[CALL2:%.*]] = call i8* @strcat(i8* [[P]], i8* [[Q]])
|
; CHECK-NEXT: [[CALL2:%.*]] = call ptr @strcat(ptr [[P]], ptr [[Q]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%call1 = call i8* @strcat(i8* %P, i8* %Q)
|
%call1 = call ptr @strcat(ptr %P, ptr %Q)
|
||||||
; FIXME: Eliminate the second strcat as a "store of existing value" for this particular case, where both strcat's are identical (same source, not just same dest).
|
; FIXME: Eliminate the second strcat as a "store of existing value" for this particular case, where both strcat's are identical (same source, not just same dest).
|
||||||
%call2 = call i8* @strcat(i8* %P, i8* %Q)
|
%call2 = call ptr @strcat(ptr %P, ptr %Q)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @pr49927(i32* %q, i32* %p) {
|
define void @pr49927(ptr %q, ptr %p) {
|
||||||
; CHECK-LABEL: @pr49927(
|
; CHECK-LABEL: @pr49927(
|
||||||
; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[P:%.*]], align 4
|
; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4
|
||||||
; CHECK-NEXT: store i32 [[V]], i32* [[Q:%.*]], align 4
|
; CHECK-NEXT: store i32 [[V]], ptr [[Q:%.*]], align 4
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%v = load i32, i32* %p, align 4
|
%v = load i32, ptr %p, align 4
|
||||||
store i32 %v, i32* %q, align 4
|
store i32 %v, ptr %q, align 4
|
||||||
store i32 %v, i32* %p, align 4
|
store i32 %v, ptr %p, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @pr50339(i8* nocapture readonly %0) {
|
define void @pr50339(ptr nocapture readonly %0) {
|
||||||
; CHECK-LABEL: @pr50339(
|
; CHECK-LABEL: @pr50339(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 16 dereferenceable(16) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i64 0, i64 0), i8* noundef nonnull align 1 dereferenceable(16) [[TMP0:%.*]], i64 16, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(16) @a, ptr noundef nonnull align 1 dereferenceable(16) [[TMP0:%.*]], i64 16, i1 false)
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 16 dereferenceable(16) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i64 0, i64 0), i8* noundef nonnull align 1 dereferenceable(16) [[TMP0]], i64 16, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(16) @a, ptr noundef nonnull align 1 dereferenceable(16) [[TMP0]], i64 16, i1 false)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 16 dereferenceable(16) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i64 0, i64 0), i8* noundef nonnull align 1 dereferenceable(16) %0, i64 16, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(16) @a, ptr noundef nonnull align 1 dereferenceable(16) %0, i64 16, i1 false)
|
||||||
; FIXME: Eliminate the second memcpy as a "store of existing value" for this particular case, where both memcpy's are identical (same source, not just same dest).
|
; FIXME: Eliminate the second memcpy as a "store of existing value" for this particular case, where both memcpy's are identical (same source, not just same dest).
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 16 dereferenceable(16) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i64 0, i64 0), i8* noundef nonnull align 1 dereferenceable(16) %0, i64 16, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(16) @a, ptr noundef nonnull align 1 dereferenceable(16) %0, i64 16, i1 false)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Cannot remove the second memcpy as redundant store, because %src is modified
|
; Cannot remove the second memcpy as redundant store, because %src is modified
|
||||||
; in between.
|
; in between.
|
||||||
define i8 @memset_optimized_access(i8* noalias %dst, i8* noalias %src) {
|
define i8 @memset_optimized_access(ptr noalias %dst, ptr noalias %src) {
|
||||||
; CHECK-LABEL: @memset_optimized_access(
|
; CHECK-LABEL: @memset_optimized_access(
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 16, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 16, i1 false)
|
||||||
; CHECK-NEXT: store i8 99, i8* [[SRC]], align 1
|
; CHECK-NEXT: store i8 99, ptr [[SRC]], align 1
|
||||||
; CHECK-NEXT: [[L:%.*]] = load i8, i8* [[DST]], align 1
|
; CHECK-NEXT: [[L:%.*]] = load i8, ptr [[DST]], align 1
|
||||||
; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC]], i64 16, i1 false)
|
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[DST]], ptr [[SRC]], i64 16, i1 false)
|
||||||
; CHECK-NEXT: ret i8 [[L]]
|
; CHECK-NEXT: ret i8 [[L]]
|
||||||
;
|
;
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 16, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 16, i1 false)
|
||||||
store i8 99, i8* %src
|
store i8 99, ptr %src
|
||||||
%l = load i8, i8* %dst
|
%l = load i8, ptr %dst
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 16, i1 false)
|
tail call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 16, i1 false)
|
||||||
ret i8 %l
|
ret i8 %l
|
||||||
}
|
}
|
||||||
|
|
||||||
; The @use() call is a later non-removable store, but should not affect the
|
; The @use() call is a later non-removable store, but should not affect the
|
||||||
; removal of the store in the if block.
|
; removal of the store in the if block.
|
||||||
define void @later_non_removable_store(i1 %c, i8* %p) {
|
define void @later_non_removable_store(i1 %c, ptr %p) {
|
||||||
; CHECK-LABEL: @later_non_removable_store(
|
; CHECK-LABEL: @later_non_removable_store(
|
||||||
; CHECK-NEXT: store i8 1, i8* [[P:%.*]], align 1
|
; CHECK-NEXT: store i8 1, ptr [[P:%.*]], align 1
|
||||||
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[EXIT:%.*]]
|
; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[EXIT:%.*]]
|
||||||
; CHECK: if:
|
; CHECK: if:
|
||||||
; CHECK-NEXT: br label [[EXIT]]
|
; CHECK-NEXT: br label [[EXIT]]
|
||||||
; CHECK: exit:
|
; CHECK: exit:
|
||||||
; CHECK-NEXT: call void @use(i8* [[P]]) #[[ATTR6:[0-9]+]]
|
; CHECK-NEXT: call void @use(ptr [[P]]) #[[ATTR6:[0-9]+]]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
store i8 1, i8* %p
|
store i8 1, ptr %p
|
||||||
br i1 %c, label %if, label %exit
|
br i1 %c, label %if, label %exit
|
||||||
|
|
||||||
if:
|
if:
|
||||||
store i8 1, i8* %p
|
store i8 1, ptr %p
|
||||||
br label %exit
|
br label %exit
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
call void @use(i8* %p) argmemonly
|
call void @use(ptr %p) argmemonly
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,16 +8,16 @@
|
||||||
target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
|
target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
|
||||||
target triple = "i386-unknown-linux-gnu"
|
target triple = "i386-unknown-linux-gnu"
|
||||||
|
|
||||||
declare void @g(i32* byval(i32) %p)
|
declare void @g(ptr byval(i32) %p)
|
||||||
|
|
||||||
define void @f(i32* byval(i32) %x) {
|
define void @f(ptr byval(i32) %x) {
|
||||||
entry:
|
entry:
|
||||||
%p = alloca i32
|
%p = alloca i32
|
||||||
%v = load i32, i32* %x
|
%v = load i32, ptr %x
|
||||||
store i32 %v, i32* %p
|
store i32 %v, ptr %p
|
||||||
tail call void @g(i32* byval(i32) %p)
|
tail call void @g(ptr byval(i32) %p)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
; CHECK-LABEL: define void @f(i32* byval(i32) %x)
|
; CHECK-LABEL: define void @f(ptr byval(i32) %x)
|
||||||
; CHECK: store i32 %v, i32* %p
|
; CHECK: store i32 %v, ptr %p
|
||||||
; CHECK: tail call void @g(i32* byval(i32) %p)
|
; CHECK: tail call void @g(ptr byval(i32) %p)
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||||
; RUN: opt -dse -S < %s | FileCheck %s
|
; RUN: opt -dse -S < %s | FileCheck %s
|
||||||
|
|
||||||
declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)
|
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
|
||||||
declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
|
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
|
||||||
|
|
||||||
declare void @unknown()
|
declare void @unknown()
|
||||||
declare void @f(i8*)
|
declare void @f(ptr)
|
||||||
declare void @f2(i8*, i8*)
|
declare void @f2(ptr, ptr)
|
||||||
declare i8* @f3(i8*, i8*)
|
declare ptr @f3(ptr, ptr)
|
||||||
|
|
||||||
; Basic case for DSEing a trivially dead writing call
|
; Basic case for DSEing a trivially dead writing call
|
||||||
define void @test_dead() {
|
define void @test_dead() {
|
||||||
|
@ -15,8 +15,7 @@ define void @test_dead() {
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%bitcast = bitcast i32* %a to i8*
|
call void @f(ptr writeonly nocapture %a) argmemonly nounwind willreturn
|
||||||
call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,16 +23,14 @@ define void @test_dead() {
|
||||||
define void @test_lifetime() {
|
define void @test_lifetime() {
|
||||||
; CHECK-LABEL: @test_lifetime(
|
; CHECK-LABEL: @test_lifetime(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[A]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[BITCAST]])
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[A]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[BITCAST]])
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%bitcast = bitcast i32* %a to i8*
|
call void @llvm.lifetime.start.p0(i64 4, ptr %a)
|
||||||
call void @llvm.lifetime.start.p0i8(i64 4, i8* %bitcast)
|
call void @f(ptr writeonly nocapture %a) argmemonly nounwind willreturn
|
||||||
call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn
|
call void @llvm.lifetime.end.p0(i64 4, ptr %a)
|
||||||
call void @llvm.lifetime.end.p0i8(i64 4, i8* %bitcast)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,20 +39,18 @@ define void @test_lifetime() {
|
||||||
define void @test_lifetime2() {
|
define void @test_lifetime2() {
|
||||||
; CHECK-LABEL: @test_lifetime2(
|
; CHECK-LABEL: @test_lifetime2(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr [[A]])
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[BITCAST]])
|
|
||||||
; CHECK-NEXT: call void @unknown()
|
; CHECK-NEXT: call void @unknown()
|
||||||
; CHECK-NEXT: call void @unknown()
|
; CHECK-NEXT: call void @unknown()
|
||||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[BITCAST]])
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr [[A]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%bitcast = bitcast i32* %a to i8*
|
call void @llvm.lifetime.start.p0(i64 4, ptr %a)
|
||||||
call void @llvm.lifetime.start.p0i8(i64 4, i8* %bitcast)
|
|
||||||
call void @unknown()
|
call void @unknown()
|
||||||
call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn
|
call void @f(ptr writeonly nocapture %a) argmemonly nounwind willreturn
|
||||||
call void @unknown()
|
call void @unknown()
|
||||||
call void @llvm.lifetime.end.p0i8(i64 4, i8* %bitcast)
|
call void @llvm.lifetime.end.p0(i64 4, ptr %a)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,23 +61,20 @@ define void @test_dead_readwrite() {
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%bitcast = bitcast i32* %a to i8*
|
call void @f(ptr nocapture %a) argmemonly nounwind willreturn
|
||||||
call void @f(i8* nocapture %bitcast) argmemonly nounwind willreturn
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test_neg_read_after() {
|
define i32 @test_neg_read_after() {
|
||||||
; CHECK-LABEL: @test_neg_read_after(
|
; CHECK-LABEL: @test_neg_read_after(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
|
; CHECK-NEXT: call void @f(ptr nocapture writeonly [[A]]) #[[ATTR1:[0-9]+]]
|
||||||
; CHECK-NEXT: call void @f(i8* nocapture writeonly [[BITCAST]]) #[[ATTR1:[0-9]+]]
|
; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: [[RES:%.*]] = load i32, i32* [[A]], align 4
|
|
||||||
; CHECK-NEXT: ret i32 [[RES]]
|
; CHECK-NEXT: ret i32 [[RES]]
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%bitcast = bitcast i32* %a to i8*
|
call void @f(ptr writeonly nocapture %a) argmemonly nounwind willreturn
|
||||||
call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn
|
%res = load i32, ptr %a
|
||||||
%res = load i32, i32* %a
|
|
||||||
ret i32 %res
|
ret i32 %res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,39 +82,33 @@ define i32 @test_neg_read_after() {
|
||||||
define void @test_neg_infinite_loop() {
|
define void @test_neg_infinite_loop() {
|
||||||
; CHECK-LABEL: @test_neg_infinite_loop(
|
; CHECK-LABEL: @test_neg_infinite_loop(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
|
; CHECK-NEXT: call void @f(ptr nocapture writeonly [[A]]) #[[ATTR2:[0-9]+]]
|
||||||
; CHECK-NEXT: call void @f(i8* nocapture writeonly [[BITCAST]]) #[[ATTR2:[0-9]+]]
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%bitcast = bitcast i32* %a to i8*
|
call void @f(ptr writeonly nocapture %a) argmemonly nounwind
|
||||||
call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test_neg_throw() {
|
define void @test_neg_throw() {
|
||||||
; CHECK-LABEL: @test_neg_throw(
|
; CHECK-LABEL: @test_neg_throw(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
|
; CHECK-NEXT: call void @f(ptr nocapture writeonly [[A]]) #[[ATTR3:[0-9]+]]
|
||||||
; CHECK-NEXT: call void @f(i8* nocapture writeonly [[BITCAST]]) #[[ATTR3:[0-9]+]]
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%bitcast = bitcast i32* %a to i8*
|
call void @f(ptr writeonly nocapture %a) argmemonly willreturn
|
||||||
call void @f(i8* writeonly nocapture %bitcast) argmemonly willreturn
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test_neg_extra_write() {
|
define void @test_neg_extra_write() {
|
||||||
; CHECK-LABEL: @test_neg_extra_write(
|
; CHECK-LABEL: @test_neg_extra_write(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
|
; CHECK-NEXT: call void @f(ptr nocapture writeonly [[A]]) #[[ATTR4:[0-9]+]]
|
||||||
; CHECK-NEXT: call void @f(i8* nocapture writeonly [[BITCAST]]) #[[ATTR4:[0-9]+]]
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%bitcast = bitcast i32* %a to i8*
|
call void @f(ptr writeonly nocapture %a) nounwind willreturn
|
||||||
call void @f(i8* writeonly nocapture %bitcast) nounwind willreturn
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,64 +118,48 @@ define void @test_neg_unmodeled_write() {
|
||||||
; CHECK-LABEL: @test_neg_unmodeled_write(
|
; CHECK-LABEL: @test_neg_unmodeled_write(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[A2:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A2:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
|
; CHECK-NEXT: call void @f2(ptr nocapture writeonly [[A]], ptr [[A2]]) #[[ATTR1]]
|
||||||
; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast i32* [[A2]] to i8*
|
|
||||||
; CHECK-NEXT: call void @f2(i8* nocapture writeonly [[BITCAST]], i8* [[BITCAST2]]) #[[ATTR1]]
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%a2 = alloca i32, align 4
|
%a2 = alloca i32, align 4
|
||||||
%bitcast = bitcast i32* %a to i8*
|
call void @f2(ptr nocapture writeonly %a, ptr %a2) argmemonly nounwind willreturn
|
||||||
%bitcast2 = bitcast i32* %a2 to i8*
|
|
||||||
call void @f2(i8* nocapture writeonly %bitcast, i8* %bitcast2) argmemonly nounwind willreturn
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test_neg_captured_by_call() {
|
define i32 @test_neg_captured_by_call() {
|
||||||
; CHECK-LABEL: @test_neg_captured_by_call(
|
; CHECK-LABEL: @test_neg_captured_by_call(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[A2:%.*]] = alloca i8*, align 4
|
; CHECK-NEXT: [[A2:%.*]] = alloca ptr, align 4
|
||||||
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
|
; CHECK-NEXT: call void @f2(ptr writeonly [[A]], ptr [[A2]]) #[[ATTR1]]
|
||||||
; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast i8** [[A2]] to i8*
|
; CHECK-NEXT: [[A_COPY_CAST:%.*]] = load ptr, ptr [[A2]], align 8
|
||||||
; CHECK-NEXT: call void @f2(i8* writeonly [[BITCAST]], i8* [[BITCAST2]]) #[[ATTR1]]
|
; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[A_COPY_CAST]], align 4
|
||||||
; CHECK-NEXT: [[A_COPY_CAST:%.*]] = load i8*, i8** [[A2]], align 8
|
|
||||||
; CHECK-NEXT: [[A_COPY:%.*]] = bitcast i8* [[A_COPY_CAST]] to i32*
|
|
||||||
; CHECK-NEXT: [[RES:%.*]] = load i32, i32* [[A_COPY]], align 4
|
|
||||||
; CHECK-NEXT: ret i32 [[RES]]
|
; CHECK-NEXT: ret i32 [[RES]]
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%a2 = alloca i8*, align 4
|
%a2 = alloca ptr, align 4
|
||||||
%bitcast = bitcast i32* %a to i8*
|
call void @f2(ptr writeonly %a, ptr %a2) argmemonly nounwind willreturn
|
||||||
%bitcast2 = bitcast i8** %a2 to i8*
|
%a_copy_cast = load ptr, ptr %a2
|
||||||
call void @f2(i8* writeonly %bitcast, i8* %bitcast2) argmemonly nounwind willreturn
|
%res = load i32, ptr %a_copy_cast
|
||||||
%a_copy_cast = load i8*, i8** %a2
|
|
||||||
%a_copy = bitcast i8* %a_copy_cast to i32*
|
|
||||||
%res = load i32, i32* %a_copy
|
|
||||||
ret i32 %res
|
ret i32 %res
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test_neg_captured_before() {
|
define i32 @test_neg_captured_before() {
|
||||||
; CHECK-LABEL: @test_neg_captured_before(
|
; CHECK-LABEL: @test_neg_captured_before(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[A2:%.*]] = alloca i8*, align 4
|
; CHECK-NEXT: [[A2:%.*]] = alloca ptr, align 4
|
||||||
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
|
; CHECK-NEXT: store ptr [[A]], ptr [[A2]], align 8
|
||||||
; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast i8** [[A2]] to i8*
|
; CHECK-NEXT: call void @f(ptr nocapture writeonly [[A]]) #[[ATTR1]]
|
||||||
; CHECK-NEXT: store i8* [[BITCAST]], i8** [[A2]], align 8
|
; CHECK-NEXT: [[A_COPY_CAST:%.*]] = load ptr, ptr [[A2]], align 8
|
||||||
; CHECK-NEXT: call void @f(i8* nocapture writeonly [[BITCAST]]) #[[ATTR1]]
|
; CHECK-NEXT: [[RES:%.*]] = load i32, ptr [[A_COPY_CAST]], align 4
|
||||||
; CHECK-NEXT: [[A_COPY_CAST:%.*]] = load i8*, i8** [[A2]], align 8
|
|
||||||
; CHECK-NEXT: [[A_COPY:%.*]] = bitcast i8* [[A_COPY_CAST]] to i32*
|
|
||||||
; CHECK-NEXT: [[RES:%.*]] = load i32, i32* [[A_COPY]], align 4
|
|
||||||
; CHECK-NEXT: ret i32 [[RES]]
|
; CHECK-NEXT: ret i32 [[RES]]
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%a2 = alloca i8*, align 4
|
%a2 = alloca ptr, align 4
|
||||||
%bitcast = bitcast i32* %a to i8*
|
store ptr %a, ptr %a2
|
||||||
%bitcast2 = bitcast i8** %a2 to i8*
|
call void @f(ptr writeonly nocapture %a) argmemonly nounwind willreturn
|
||||||
store i8* %bitcast, i8** %a2
|
%a_copy_cast = load ptr, ptr %a2
|
||||||
call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn
|
%res = load i32, ptr %a_copy_cast
|
||||||
%a_copy_cast = load i8*, i8** %a2
|
|
||||||
%a_copy = bitcast i8* %a_copy_cast to i32*
|
|
||||||
%res = load i32, i32* %a_copy
|
|
||||||
ret i32 %res
|
ret i32 %res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,13 +167,11 @@ define i32 @test_neg_captured_before() {
|
||||||
define void @test_new_op_bundle() {
|
define void @test_new_op_bundle() {
|
||||||
; CHECK-LABEL: @test_new_op_bundle(
|
; CHECK-LABEL: @test_new_op_bundle(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
|
; CHECK-NEXT: call void @f(ptr nocapture writeonly [[A]]) #[[ATTR1]] [ "unknown"(ptr [[A]]) ]
|
||||||
; CHECK-NEXT: call void @f(i8* nocapture writeonly [[BITCAST]]) #[[ATTR1]] [ "unknown"(i8* [[BITCAST]]) ]
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%bitcast = bitcast i32* %a to i8*
|
call void @f(ptr writeonly nocapture %a) argmemonly nounwind willreturn ["unknown" (ptr %a)]
|
||||||
call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn ["unknown" (i8* %bitcast)]
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,9 +182,7 @@ define void @test_unreleated_read() {
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%a2 = alloca i32, align 4
|
%a2 = alloca i32, align 4
|
||||||
%bitcast = bitcast i32* %a to i8*
|
call void @f2(ptr nocapture writeonly %a, ptr nocapture readonly %a2) argmemonly nounwind willreturn
|
||||||
%bitcast2 = bitcast i32* %a2 to i8*
|
|
||||||
call void @f2(i8* nocapture writeonly %bitcast, i8* nocapture readonly %bitcast2) argmemonly nounwind willreturn
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,29 +194,23 @@ define void @test_unrelated_capture() {
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%a2 = alloca i32, align 4
|
%a2 = alloca i32, align 4
|
||||||
%bitcast = bitcast i32* %a to i8*
|
call ptr @f3(ptr nocapture writeonly %a, ptr readonly %a2) argmemonly nounwind willreturn
|
||||||
%bitcast2 = bitcast i32* %a2 to i8*
|
|
||||||
call i8* @f3(i8* nocapture writeonly %bitcast, i8* readonly %bitcast2) argmemonly nounwind willreturn
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; Cannot remove call, as %bitcast2 is captured via the return value.
|
; Cannot remove call, as %a2 is captured via the return value.
|
||||||
define i8 @test_neg_unrelated_capture_used_via_return() {
|
define i8 @test_neg_unrelated_capture_used_via_return() {
|
||||||
; CHECK-LABEL: @test_neg_unrelated_capture_used_via_return(
|
; CHECK-LABEL: @test_neg_unrelated_capture_used_via_return(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[A2:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A2:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
|
; CHECK-NEXT: [[CAPTURE:%.*]] = call ptr @f3(ptr nocapture writeonly [[A]], ptr readonly [[A2]]) #[[ATTR1]]
|
||||||
; CHECK-NEXT: [[BITCAST2:%.*]] = bitcast i32* [[A2]] to i8*
|
; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[CAPTURE]], align 1
|
||||||
; CHECK-NEXT: [[CAPTURE:%.*]] = call i8* @f3(i8* nocapture writeonly [[BITCAST]], i8* readonly [[BITCAST2]]) #[[ATTR1]]
|
|
||||||
; CHECK-NEXT: [[V:%.*]] = load i8, i8* [[CAPTURE]], align 1
|
|
||||||
; CHECK-NEXT: ret i8 [[V]]
|
; CHECK-NEXT: ret i8 [[V]]
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%a2 = alloca i32, align 4
|
%a2 = alloca i32, align 4
|
||||||
%bitcast = bitcast i32* %a to i8*
|
%capture = call ptr @f3(ptr nocapture writeonly %a, ptr readonly %a2) argmemonly nounwind willreturn
|
||||||
%bitcast2 = bitcast i32* %a2 to i8*
|
%v = load i8, ptr %capture
|
||||||
%capture = call i8* @f3(i8* nocapture writeonly %bitcast, i8* readonly %bitcast2) argmemonly nounwind willreturn
|
|
||||||
%v = load i8, i8* %capture
|
|
||||||
ret i8 %v
|
ret i8 %v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,8 +221,7 @@ define void @test_self_read() {
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%bitcast = bitcast i32* %a to i8*
|
call void @f2(ptr nocapture writeonly %a, ptr nocapture readonly %a) argmemonly nounwind willreturn
|
||||||
call void @f2(i8* nocapture writeonly %bitcast, i8* nocapture readonly %bitcast) argmemonly nounwind willreturn
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,15 +231,14 @@ define void @test_self_read() {
|
||||||
define i32 @test_dse_overwrite() {
|
define i32 @test_dse_overwrite() {
|
||||||
; CHECK-LABEL: @test_dse_overwrite(
|
; CHECK-LABEL: @test_dse_overwrite(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: store i32 0, i32* [[A]], align 4
|
; CHECK-NEXT: store i32 0, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[A]], align 4
|
; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: ret i32 [[V]]
|
; CHECK-NEXT: ret i32 [[V]]
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%bitcast = bitcast i32* %a to i8*
|
call void @f(ptr writeonly nocapture %a) argmemonly nounwind willreturn
|
||||||
call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn
|
store i32 0, ptr %a
|
||||||
store i32 0, i32* %a
|
%v = load i32, ptr %a
|
||||||
%v = load i32, i32* %a
|
|
||||||
ret i32 %v
|
ret i32 %v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,34 +246,30 @@ define i32 @test_dse_overwrite() {
|
||||||
define i32 @test_neg_dse_partial_overwrite() {
|
define i32 @test_neg_dse_partial_overwrite() {
|
||||||
; CHECK-LABEL: @test_neg_dse_partial_overwrite(
|
; CHECK-LABEL: @test_neg_dse_partial_overwrite(
|
||||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8*
|
; CHECK-NEXT: call void @f(ptr nocapture writeonly [[A]]) #[[ATTR1]]
|
||||||
; CHECK-NEXT: call void @f(i8* nocapture writeonly [[BITCAST]]) #[[ATTR1]]
|
; CHECK-NEXT: store i8 0, ptr [[A]], align 1
|
||||||
; CHECK-NEXT: store i8 0, i8* [[BITCAST]], align 1
|
; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[A]], align 4
|
|
||||||
; CHECK-NEXT: ret i32 [[V]]
|
; CHECK-NEXT: ret i32 [[V]]
|
||||||
;
|
;
|
||||||
%a = alloca i32, align 4
|
%a = alloca i32, align 4
|
||||||
%bitcast = bitcast i32* %a to i8*
|
call void @f(ptr writeonly nocapture %a) argmemonly nounwind willreturn
|
||||||
call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn
|
store i8 0, ptr %a
|
||||||
store i8 0, i8* %bitcast
|
%v = load i32, ptr %a
|
||||||
%v = load i32, i32* %a
|
|
||||||
ret i32 %v
|
ret i32 %v
|
||||||
}
|
}
|
||||||
|
|
||||||
; Negative case where we don't know the size of a, and thus can't use the
|
; Negative case where we don't know the size of a, and thus can't use the
|
||||||
; full overwrite reasoning
|
; full overwrite reasoning
|
||||||
define i32 @test_neg_dse_unsized(i32* %a) {
|
define i32 @test_neg_dse_unsized(ptr %a) {
|
||||||
; CHECK-LABEL: @test_neg_dse_unsized(
|
; CHECK-LABEL: @test_neg_dse_unsized(
|
||||||
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A:%.*]] to i8*
|
; CHECK-NEXT: call void @f(ptr nocapture writeonly [[A:%.*]]) #[[ATTR1]]
|
||||||
; CHECK-NEXT: call void @f(i8* nocapture writeonly [[BITCAST]]) #[[ATTR1]]
|
; CHECK-NEXT: store i32 0, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: store i32 0, i32* [[A]], align 4
|
; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[A]], align 4
|
||||||
; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[A]], align 4
|
|
||||||
; CHECK-NEXT: ret i32 [[V]]
|
; CHECK-NEXT: ret i32 [[V]]
|
||||||
;
|
;
|
||||||
%bitcast = bitcast i32* %a to i8*
|
call void @f(ptr writeonly nocapture %a) argmemonly nounwind willreturn
|
||||||
call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn
|
store i32 0, ptr %a
|
||||||
store i32 0, i32* %a
|
%v = load i32, ptr %a
|
||||||
%v = load i32, i32* %a
|
|
||||||
ret i32 %v
|
ret i32 %v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,11 +278,11 @@ define i32 @test_neg_dse_unsized(i32* %a) {
|
||||||
; Same as test_dse_overwrite, but with a non-alloca object.
|
; Same as test_dse_overwrite, but with a non-alloca object.
|
||||||
define void @test_dse_non_alloca() {
|
define void @test_dse_non_alloca() {
|
||||||
; CHECK-LABEL: @test_dse_non_alloca(
|
; CHECK-LABEL: @test_dse_non_alloca(
|
||||||
; CHECK-NEXT: store i8 0, i8* @G, align 1
|
; CHECK-NEXT: store i8 0, ptr @G, align 1
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @f(i8* writeonly nocapture @G) argmemonly nounwind willreturn
|
call void @f(ptr writeonly nocapture @G) argmemonly nounwind willreturn
|
||||||
store i8 0, i8* @G
|
store i8 0, ptr @G
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,17 +2,17 @@
|
||||||
; RUN: opt -S -dse < %s | FileCheck %s
|
; RUN: opt -S -dse < %s | FileCheck %s
|
||||||
|
|
||||||
; malloc should have i64 argument under default data layout
|
; malloc should have i64 argument under default data layout
|
||||||
declare noalias i8* @malloc(i32)
|
declare noalias ptr @malloc(i32)
|
||||||
|
|
||||||
define i8* @malloc_and_memset_intrinsic(i32 %n) {
|
define ptr @malloc_and_memset_intrinsic(i32 %n) {
|
||||||
; CHECK-LABEL: @malloc_and_memset_intrinsic(
|
; CHECK-LABEL: @malloc_and_memset_intrinsic(
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = call i8* @malloc(i32 [[N:%.*]])
|
; CHECK-NEXT: [[CALL:%.*]] = call ptr @malloc(i32 [[N:%.*]])
|
||||||
; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 [[CALL]], i8 0, i32 [[N]], i1 false)
|
; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 1 [[CALL]], i8 0, i32 [[N]], i1 false)
|
||||||
; CHECK-NEXT: ret i8* [[CALL]]
|
; CHECK-NEXT: ret ptr [[CALL]]
|
||||||
;
|
;
|
||||||
%call = call i8* @malloc(i32 %n)
|
%call = call ptr @malloc(i32 %n)
|
||||||
call void @llvm.memset.p0i8.i32(i8* align 1 %call, i8 0, i32 %n, i1 false)
|
call void @llvm.memset.p0.i32(ptr align 1 %call, i8 0, i32 %n, i1 false)
|
||||||
ret i8* %call
|
ret ptr %call
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.memset.p0i8.i32(i8* nocapture writeonly, i8, i32, i1 immarg) #2
|
declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg) #2
|
||||||
|
|
Loading…
Reference in New Issue