1 ; RUN: opt -instcombine -S %s | FileCheck %s 2 target datalayout = "p:32:32" 3 4 5 define i1 @alloca_argument_compare(i64* %arg) { 6 %alloc = alloca i64 7 %cmp = icmp eq i64* %arg, %alloc 8 ret i1 %cmp 9 ; CHECK-LABEL: alloca_argument_compare 10 ; CHECK: ret i1 false 11 } 12 13 define i1 @alloca_argument_compare_swapped(i64* %arg) { 14 %alloc = alloca i64 15 %cmp = icmp eq i64* %alloc, %arg 16 ret i1 %cmp 17 ; CHECK-LABEL: alloca_argument_compare_swapped 18 ; CHECK: ret i1 false 19 } 20 21 define i1 @alloca_argument_compare_ne(i64* %arg) { 22 %alloc = alloca i64 23 %cmp = icmp ne i64* %arg, %alloc 24 ret i1 %cmp 25 ; CHECK-LABEL: alloca_argument_compare_ne 26 ; CHECK: ret i1 true 27 } 28 29 define i1 @alloca_argument_compare_derived_ptrs(i64* %arg, i64 %x) { 30 %alloc = alloca i64, i64 8 31 %p = getelementptr i64, i64* %arg, i64 %x 32 %q = getelementptr i64, i64* %alloc, i64 3 33 %cmp = icmp eq i64* %p, %q 34 ret i1 %cmp 35 ; CHECK-LABEL: alloca_argument_compare_derived_ptrs 36 ; CHECK: ret i1 false 37 } 38 39 declare void @escape(i64*) 40 define i1 @alloca_argument_compare_escaped_alloca(i64* %arg) { 41 %alloc = alloca i64 42 call void @escape(i64* %alloc) 43 %cmp = icmp eq i64* %alloc, %arg 44 ret i1 %cmp 45 ; CHECK-LABEL: alloca_argument_compare_escaped_alloca 46 ; CHECK: %cmp = icmp eq i64* %alloc, %arg 47 ; CHECK: ret i1 %cmp 48 } 49 50 declare void @check_compares(i1, i1) 51 define void @alloca_argument_compare_two_compares(i64* %p) { 52 %q = alloca i64, i64 8 53 %r = getelementptr i64, i64* %p, i64 1 54 %s = getelementptr i64, i64* %q, i64 2 55 %cmp1 = icmp eq i64* %p, %q 56 %cmp2 = icmp eq i64* %r, %s 57 call void @check_compares(i1 %cmp1, i1 %cmp2) 58 ret void 59 ; We will only fold if there is a single cmp. 60 ; CHECK-LABEL: alloca_argument_compare_two_compares 61 ; CHECK: call void @check_compares(i1 %cmp1, i1 %cmp2) 62 } 63 64 define i1 @alloca_argument_compare_escaped_through_store(i64* %arg, i64** %ptr) { 65 %alloc = alloca i64 66 %cmp = icmp eq i64* %alloc, %arg 67 %p = getelementptr i64, i64* %alloc, i64 1 68 store i64* %p, i64** %ptr 69 ret i1 %cmp 70 ; CHECK-LABEL: alloca_argument_compare_escaped_through_store 71 ; CHECK: %cmp = icmp eq i64* %alloc, %arg 72 ; CHECK: ret i1 %cmp 73 } 74 75 declare void @llvm.lifetime.start(i64, i8* nocapture) 76 declare void @llvm.lifetime.end(i64, i8* nocapture) 77 define i1 @alloca_argument_compare_benign_instrs(i8* %arg) { 78 %alloc = alloca i8 79 call void @llvm.lifetime.start(i64 1, i8* %alloc) 80 %cmp = icmp eq i8* %arg, %alloc 81 %x = load i8, i8* %arg 82 store i8 %x, i8* %alloc 83 call void @llvm.lifetime.end(i64 1, i8* %alloc) 84 ret i1 %cmp 85 ; CHECK-LABEL: alloca_argument_compare_benign_instrs 86 ; CHECK: ret i1 false 87 } 88 89 declare i64* @allocator() 90 define i1 @alloca_call_compare() { 91 %p = alloca i64 92 %q = call i64* @allocator() 93 %cmp = icmp eq i64* %p, %q 94 ret i1 %cmp 95 ; CHECK-LABEL: alloca_call_compare 96 ; CHECK: ret i1 false 97 } 98