1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=newgvn -enable-phi-of-ops=true -S < %s | FileCheck %s 3; RUN: opt -passes=newgvn -enable-phi-of-ops=true -S -o - %s | FileCheck %s 4 5target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" 6 7;; All the loads in this testcase are useless, but it requires understanding that repeated 8;; stores of the same value do not change the memory state to eliminate them. 9 10define i32 @foo(ptr, i32) { 11; CHECK-LABEL: @foo( 12; CHECK-NEXT: store i32 5, ptr [[TMP0:%.*]], align 4 13; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1:%.*]], 0 14; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]] 15; CHECK: 4: 16; CHECK-NEXT: br label [[TMP5]] 17; CHECK: 5: 18; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ 10, [[TMP4]] ], [ 5, [[TMP2:%.*]] ] 19; CHECK-NEXT: br i1 [[TMP3]], label [[TMP6:%.*]], label [[TMP8:%.*]] 20; CHECK: 6: 21; CHECK-NEXT: [[TMP7:%.*]] = add nsw i32 [[DOT0]], 5 22; CHECK-NEXT: br label [[TMP8]] 23; CHECK: 8: 24; CHECK-NEXT: [[DOT1:%.*]] = phi i32 [ [[TMP7]], [[TMP6]] ], [ [[DOT0]], [[TMP5]] ] 25; CHECK-NEXT: ret i32 [[DOT1]] 26; 27 store i32 5, ptr %0, align 4 28 %3 = icmp ne i32 %1, 0 29 br i1 %3, label %4, label %7 30 31; <label>:4: ; preds = %2 32 %5 = load i32, ptr %0, align 4 33 %6 = add nsw i32 5, %5 34 br label %7 35 36; <label>:7: ; preds = %4, %2 37 %.0 = phi i32 [ %6, %4 ], [ 5, %2 ] 38 store i32 5, ptr %0, align 4 39 %8 = icmp ne i32 %1, 0 40 br i1 %8, label %9, label %12 41 42; <label>:9: ; preds = %7 43 %10 = load i32, ptr %0, align 4 44 %11 = add nsw i32 %.0, %10 45 br label %12 46 47; <label>:12: ; preds = %9, %7 48 %.1 = phi i32 [ %11, %9 ], [ %.0, %7 ] 49 ret i32 %.1 50} 51 52;; This is similar to the above, but it is a conditional store of the same value 53;; which requires value numbering MemoryPhi properly to resolve. 54define i32 @foo2(ptr, i32) { 55; CHECK-LABEL: @foo2( 56; CHECK-NEXT: store i32 5, ptr [[TMP0:%.*]], align 4 57; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1:%.*]], 0 58; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]] 59; CHECK: 4: 60; CHECK-NEXT: br label [[TMP6:%.*]] 61; CHECK: 5: 62; CHECK-NEXT: br label [[TMP6]] 63; CHECK: 6: 64; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ 10, [[TMP4]] ], [ 5, [[TMP5]] ] 65; CHECK-NEXT: br i1 [[TMP3]], label [[TMP7:%.*]], label [[TMP9:%.*]] 66; CHECK: 7: 67; CHECK-NEXT: [[TMP8:%.*]] = add nsw i32 [[DOT0]], 5 68; CHECK-NEXT: br label [[TMP9]] 69; CHECK: 9: 70; CHECK-NEXT: [[DOT1:%.*]] = phi i32 [ [[TMP8]], [[TMP7]] ], [ [[DOT0]], [[TMP6]] ] 71; CHECK-NEXT: ret i32 [[DOT1]] 72; 73 store i32 5, ptr %0, align 4 74 %3 = icmp ne i32 %1, 0 75 br i1 %3, label %4, label %7 76 77; <label>:4: ; preds = %2 78 %5 = load i32, ptr %0, align 4 79 %6 = add nsw i32 5, %5 80 br label %8 81 82; <label>:7: ; preds = %2 83 store i32 5, ptr %0, align 4 84 br label %8 85 86; <label>:8: ; preds = %7, %4 87 %.0 = phi i32 [ %6, %4 ], [ 5, %7 ] 88 %9 = icmp ne i32 %1, 0 89 br i1 %9, label %10, label %13 90 91; <label>:10: ; preds = %8 92 %11 = load i32, ptr %0, align 4 93 %12 = add nsw i32 %.0, %11 94 br label %13 95 96; <label>:13: ; preds = %10, %8 97 %.1 = phi i32 [ %12, %10 ], [ %.0, %8 ] 98 ret i32 %.1 99} 100