; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -passes=newgvn -S | FileCheck %s define float @_Z1if(float %p) { ; CHECK-LABEL: @_Z1if( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[P_ADDR:%.*]] = alloca float, align 4 ; CHECK-NEXT: store float [[P:%.*]], float* [[P_ADDR]], align 4 ; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq float [[P]], 3.000000e+00 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) ; CHECK-NEXT: ret float [[P]] ; entry: %p.addr = alloca float, align 4 store float %p, float* %p.addr, align 4 %0 = load float, float* %p.addr, align 4 %cmp = fcmp ueq float %0, 3.000000e+00 ; no nnan flag - can't propagate call void @llvm.assume(i1 %cmp) ret float %0 } ; This test checks if constant propagation works for multiple node edges define i32 @_Z1ii(i32 %p) { ; CHECK-LABEL: @_Z1ii( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[P:%.*]], 42 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) ; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB2]] ; CHECK: bb2: ; CHECK-NEXT: br i1 true, label [[BB2]], label [[BB2]] ; CHECK: 0: ; CHECK-NEXT: store i8 poison, i8* null, align 1 ; CHECK-NEXT: ret i32 [[P]] ; entry: %cmp = icmp eq i32 %p, 42 call void @llvm.assume(i1 %cmp) br i1 %cmp, label %bb2, label %bb2 bb2: call void @llvm.assume(i1 true) br i1 %cmp, label %bb2, label %bb2 ret i32 %p } define i32 @_Z1ij(i32 %p) { ; CHECK-LABEL: @_Z1ij( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[P:%.*]], 42 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) ; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB2]] ; CHECK: bb2: ; CHECK-NEXT: call void @llvm.assume(i1 true) ; CHECK-NEXT: br i1 true, label [[TMP0:%.*]], label [[BB2]] ; CHECK: 0: ; CHECK-NEXT: ret i32 42 ; entry: %cmp = icmp eq i32 %p, 42 call void @llvm.assume(i1 %cmp) br i1 %cmp, label %bb2, label %bb2 bb2: %cmp2 = icmp eq i32 %p, 42 call void @llvm.assume(i1 %cmp2) br i1 %cmp, label %0, label %bb2 ret i32 %p } define i32 @_Z1ik(i32 %p) { ; CHECK-LABEL: @_Z1ik( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[P:%.*]], 42 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) ; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[BB3:%.*]] ; CHECK: bb2: ; CHECK-NEXT: call void @llvm.assume(i1 false) ; CHECK-NEXT: ret i32 15 ; CHECK: bb3: ; CHECK-NEXT: store i8 poison, i8* null, align 1 ; CHECK-NEXT: ret i32 17 ; entry: %cmp = icmp eq i32 %p, 42 call void @llvm.assume(i1 %cmp) br i1 %cmp, label %bb2, label %bb3 bb2: %cmp3 = icmp eq i32 %p, 43 call void @llvm.assume(i1 %cmp3) ret i32 15 bb3: ret i32 17 } ; This test checks if GVN can do the constant propagation correctly ; when there are multiple uses of the same assume value in the ; basic block that has a loop back-edge pointing to itself. define i32 @_Z1il(i32 %val, i1 %k) { ; CHECK-LABEL: @_Z1il( ; CHECK-NEXT: br label [[NEXT:%.*]] ; CHECK: next: ; CHECK-NEXT: tail call void @llvm.assume(i1 [[K:%.*]]) ; CHECK-NEXT: tail call void @llvm.assume(i1 true) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[VAL:%.*]], 50 ; CHECK-NEXT: br i1 [[CMP]], label [[NEXT]], label [[MEH:%.*]] ; CHECK: meh: ; CHECK-NEXT: ret i32 0 ; br label %next next: tail call void @llvm.assume(i1 %k) tail call void @llvm.assume(i1 %k) %cmp = icmp eq i32 %val, 50 br i1 %cmp, label %next, label %meh meh: ret i32 0 } ; This test checks if GVN can prevent the constant propagation correctly ; in the successor blocks that are not dominated by the basic block ; with the assume instruction. define i1 @_z1im(i32 %val, i1 %k, i1 %j) { ; CHECK-LABEL: @_z1im( ; CHECK-NEXT: br i1 [[J:%.*]], label [[NEXT:%.*]], label [[MEH:%.*]] ; CHECK: next: ; CHECK-NEXT: tail call void @llvm.assume(i1 [[K:%.*]]) ; CHECK-NEXT: tail call void @llvm.assume(i1 true) ; CHECK-NEXT: br label [[MEH]] ; CHECK: meh: ; CHECK-NEXT: ret i1 [[K]] ; br i1 %j, label %next, label %meh next: tail call void @llvm.assume(i1 %k) tail call void @llvm.assume(i1 %k) br label %meh meh: ret i1 %k } declare void @llvm.assume(i1)