1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2 ; RUN: opt < %s -basicaa -newgvn -S | FileCheck %s 3 4 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" 5 6 define i1 @patatino(i8* %blah, i32 %choice) { 7 ; CHECK-LABEL: @patatino( 8 ; CHECK-NEXT: entry: 9 ; CHECK-NEXT: br label [[WHILE_COND:%.*]] 10 ; CHECK: while.cond: 11 ; CHECK-NEXT: [[FOO:%.*]] = phi i8* [ [[BLAH:%.*]], [[ENTRY:%.*]] ], [ null, [[WHILE_BODY:%.*]] ] 12 ; CHECK-NEXT: switch i32 [[CHOICE:%.*]], label [[WHILE_BODY]] [ 13 ; CHECK-NEXT: i32 -1, label [[WHILE_END:%.*]] 14 ; CHECK-NEXT: i32 40, label [[LAND_END:%.*]] 15 ; CHECK-NEXT: ] 16 ; CHECK: land.end: 17 ; CHECK-NEXT: br label [[WHILE_END]] 18 ; CHECK: while.body: 19 ; CHECK-NEXT: br label [[WHILE_COND]] 20 ; CHECK: while.end: 21 ; CHECK-NEXT: store i8 0, i8* [[FOO]], align 1 22 ; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[BLAH]], align 1 23 ; CHECK-NEXT: [[LOADED:%.*]] = icmp eq i8 [[TMP0]], 0 24 ; CHECK-NEXT: store i8 0, i8* [[BLAH]], align 1 25 ; CHECK-NEXT: ret i1 [[LOADED]] 26 ; 27 entry: 28 br label %while.cond 29 30 while.cond: 31 %foo = phi i8* [ %blah, %entry ], [ null, %while.body ] 32 switch i32 %choice, label %while.body [ 33 i32 -1, label %while.end 34 i32 40, label %land.end 35 ] 36 37 land.end: 38 br label %while.end 39 40 while.body: 41 br label %while.cond 42 43 while.end: 44 %foo.lcssa = phi i8* [ %foo, %land.end ], [ %foo, %while.cond ] 45 ;; These two stores will initially be considered equivalent, but then proven not. 46 ;; the second store would previously end up deciding it's equivalent to a previous 47 ;; store, but it was really just finding an optimistic version of itself 48 ;; in the congruence class. 49 store i8 0, i8* %foo.lcssa, align 1 50 %0 = load i8, i8* %blah, align 1 51 %loaded = icmp eq i8 %0, 0 52 store i8 0, i8* %blah, align 1 53 ret i1 %loaded 54 } 55 56 57 ;; This is an example of a case where the memory states are equivalent solely due to unreachability, 58 ;; but the stores are not equal. 59 define void @foo(i8* %arg) { 60 ; CHECK-LABEL: @foo( 61 ; CHECK-NEXT: bb: 62 ; CHECK-NEXT: br label [[BB1:%.*]] 63 ; CHECK: bb1: 64 ; CHECK-NEXT: [[TMP:%.*]] = phi i8* [ [[ARG:%.*]], [[BB:%.*]] ], [ null, [[BB2:%.*]] ] 65 ; CHECK-NEXT: br i1 undef, label [[BB3:%.*]], label [[BB2]] 66 ; CHECK: bb2: 67 ; CHECK-NEXT: br label [[BB1]] 68 ; CHECK: bb3: 69 ; CHECK-NEXT: store i8 0, i8* [[TMP]], !g !0 70 ; CHECK-NEXT: br label [[BB4:%.*]] 71 ; CHECK: bb4: 72 ; CHECK-NEXT: br label [[BB6:%.*]] 73 ; CHECK: bb6: 74 ; CHECK-NEXT: br i1 undef, label [[BB9:%.*]], label [[BB7:%.*]] 75 ; CHECK: bb7: 76 ; CHECK-NEXT: switch i8 0, label [[BB6]] [ 77 ; CHECK-NEXT: i8 6, label [[BB8:%.*]] 78 ; CHECK-NEXT: ] 79 ; CHECK: bb8: 80 ; CHECK-NEXT: store i8 undef, i8* null 81 ; CHECK-NEXT: br label [[BB4]] 82 ; CHECK: bb9: 83 ; CHECK-NEXT: store i8 0, i8* [[ARG]], !g !0 84 ; CHECK-NEXT: unreachable 85 ; 86 bb: 87 br label %bb1 88 89 bb1: ; preds = %bb2, %bb 90 %tmp = phi i8* [ %arg, %bb ], [ null, %bb2 ] 91 br i1 undef, label %bb3, label %bb2 92 93 bb2: ; preds = %bb1 94 br label %bb1 95 96 bb3: ; preds = %bb1 97 store i8 0, i8* %tmp, !g !0 98 br label %bb4 99 100 bb4: ; preds = %bb8, %bb3 101 %tmp5 = phi i8* [ null, %bb8 ], [ %arg, %bb3 ] 102 br label %bb6 103 104 bb6: ; preds = %bb7, %bb4 105 br i1 undef, label %bb9, label %bb7 106 107 bb7: ; preds = %bb6 108 switch i8 0, label %bb6 [ 109 i8 6, label %bb8 110 ] 111 112 bb8: ; preds = %bb7 113 store i8 undef, i8* %tmp5, !g !0 114 br label %bb4 115 116 bb9: ; preds = %bb6 117 %tmp10 = phi i8* [ %tmp5, %bb6 ] 118 store i8 0, i8* %tmp10, !g !0 119 unreachable 120 } 121 122 !0 = !{} 123