1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -basicaa -newgvn -S | FileCheck %s 3 4target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" 5 6define 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; 27entry: 28 br label %while.cond 29 30while.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 37land.end: 38 br label %while.end 39 40while.body: 41 br label %while.cond 42 43while.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. 59define 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; 86bb: 87 br label %bb1 88 89bb1: ; preds = %bb2, %bb 90 %tmp = phi i8* [ %arg, %bb ], [ null, %bb2 ] 91 br i1 undef, label %bb3, label %bb2 92 93bb2: ; preds = %bb1 94 br label %bb1 95 96bb3: ; preds = %bb1 97 store i8 0, i8* %tmp, !g !0 98 br label %bb4 99 100bb4: ; preds = %bb8, %bb3 101 %tmp5 = phi i8* [ null, %bb8 ], [ %arg, %bb3 ] 102 br label %bb6 103 104bb6: ; preds = %bb7, %bb4 105 br i1 undef, label %bb9, label %bb7 106 107bb7: ; preds = %bb6 108 switch i8 0, label %bb6 [ 109 i8 6, label %bb8 110 ] 111 112bb8: ; preds = %bb7 113 store i8 undef, i8* %tmp5, !g !0 114 br label %bb4 115 116bb9: ; preds = %bb6 117 %tmp10 = phi i8* [ %tmp5, %bb6 ] 118 store i8 0, i8* %tmp10, !g !0 119 unreachable 120} 121 122!0 = !{} 123