1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -newgvn -S | FileCheck %s 3 4define float @_Z1if(float %p) { 5; CHECK-LABEL: @_Z1if( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: [[P_ADDR:%.*]] = alloca float, align 4 8; CHECK-NEXT: store float [[P:%.*]], float* [[P_ADDR]], align 4 9; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq float [[P]], 3.000000e+00 10; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 11; CHECK-NEXT: ret float [[P]] 12; 13entry: 14 %p.addr = alloca float, align 4 15 store float %p, float* %p.addr, align 4 16 17 %0 = load float, float* %p.addr, align 4 18 %cmp = fcmp ueq float %0, 3.000000e+00 ; no nnan flag - can't propagate 19 call void @llvm.assume(i1 %cmp) 20 21 ret float %0 22} 23 24; This test checks if constant propagation works for multiple node edges 25define i32 @_Z1ii(i32 %p) { 26; CHECK-LABEL: @_Z1ii( 27; CHECK-NEXT: entry: 28; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[P:%.*]], 42 29; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 30; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB2]] 31; CHECK: bb2: 32; CHECK-NEXT: br i1 true, label [[BB2]], label [[BB2]] 33; CHECK: 0: 34; CHECK-NEXT: store i8 undef, i8* null, align 1 35; CHECK-NEXT: ret i32 [[P]] 36; 37entry: 38 %cmp = icmp eq i32 %p, 42 39 call void @llvm.assume(i1 %cmp) 40 41 br i1 %cmp, label %bb2, label %bb2 42bb2: 43 call void @llvm.assume(i1 true) 44 br i1 %cmp, label %bb2, label %bb2 45 46 ret i32 %p 47} 48 49define i32 @_Z1ij(i32 %p) { 50; CHECK-LABEL: @_Z1ij( 51; CHECK-NEXT: entry: 52; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[P:%.*]], 42 53; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 54; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB2]] 55; CHECK: bb2: 56; CHECK-NEXT: call void @llvm.assume(i1 true) 57; CHECK-NEXT: br i1 true, label [[TMP0:%.*]], label [[BB2]] 58; CHECK: 0: 59; CHECK-NEXT: ret i32 42 60; 61entry: 62 %cmp = icmp eq i32 %p, 42 63 call void @llvm.assume(i1 %cmp) 64 65 br i1 %cmp, label %bb2, label %bb2 66bb2: 67 %cmp2 = icmp eq i32 %p, 42 68 call void @llvm.assume(i1 %cmp2) 69 70 br i1 %cmp, label %0, label %bb2 71 72 ret i32 %p 73} 74 75define i32 @_Z1ik(i32 %p) { 76; CHECK-LABEL: @_Z1ik( 77; CHECK-NEXT: entry: 78; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[P:%.*]], 42 79; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 80; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB3:%.*]] 81; CHECK: bb2: 82; CHECK-NEXT: call void @llvm.assume(i1 false) 83; CHECK-NEXT: ret i32 15 84; CHECK: bb3: 85; CHECK-NEXT: store i8 undef, i8* null, align 1 86; CHECK-NEXT: ret i32 17 87; 88entry: 89 %cmp = icmp eq i32 %p, 42 90 call void @llvm.assume(i1 %cmp) 91 92 br i1 %cmp, label %bb2, label %bb3 93bb2: 94 %cmp3 = icmp eq i32 %p, 43 95 call void @llvm.assume(i1 %cmp3) 96 ret i32 15 97bb3: 98 ret i32 17 99} 100 101; This test checks if GVN can do the constant propagation correctly 102; when there are multiple uses of the same assume value in the 103; basic block that has a loop back-edge pointing to itself. 104define i32 @_Z1il(i32 %val, i1 %k) { 105; CHECK-LABEL: @_Z1il( 106; CHECK-NEXT: br label [[NEXT:%.*]] 107; CHECK: next: 108; CHECK-NEXT: tail call void @llvm.assume(i1 [[K:%.*]]) 109; CHECK-NEXT: tail call void @llvm.assume(i1 [[K]]) 110; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[VAL:%.*]], 50 111; CHECK-NEXT: br i1 [[CMP]], label [[NEXT]], label [[MEH:%.*]] 112; CHECK: meh: 113; CHECK-NEXT: ret i32 0 114; 115 br label %next 116 117next: 118 tail call void @llvm.assume(i1 %k) 119 tail call void @llvm.assume(i1 %k) 120 %cmp = icmp eq i32 %val, 50 121 br i1 %cmp, label %next, label %meh 122 123meh: 124 ret i32 0 125} 126 127; This test checks if GVN can prevent the constant propagation correctly 128; in the successor blocks that are not dominated by the basic block 129; with the assume instruction. 130define i1 @_z1im(i32 %val, i1 %k, i1 %j) { 131; CHECK-LABEL: @_z1im( 132; CHECK-NEXT: br i1 [[J:%.*]], label [[NEXT:%.*]], label [[MEH:%.*]] 133; CHECK: next: 134; CHECK-NEXT: tail call void @llvm.assume(i1 [[K:%.*]]) 135; CHECK-NEXT: tail call void @llvm.assume(i1 [[K]]) 136; CHECK-NEXT: br label [[MEH]] 137; CHECK: meh: 138; CHECK-NEXT: ret i1 [[K]] 139; 140 br i1 %j, label %next, label %meh 141 142next: 143 tail call void @llvm.assume(i1 %k) 144 tail call void @llvm.assume(i1 %k) 145 br label %meh 146 147meh: 148 ret i1 %k 149} 150 151declare void @llvm.assume(i1) 152