; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 ; RUN: opt %s -passes=sccp -S | FileCheck %s declare void @use(i1) declare void @llvm.assume(i1) define void @nonnull(ptr %v) { ; CHECK-LABEL: define void @nonnull( ; CHECK-SAME: ptr [[V:%.*]]) { ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[V]]) ] ; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: ret void ; call void @llvm.assume(i1 true) [ "nonnull"(ptr %v) ] %c1 = icmp eq ptr %v, null call void @use(i1 %c1) %c2 = icmp ne ptr %v, null call void @use(i1 %c2) %c3 = icmp eq ptr null, %v call void @use(i1 %c3) %c4 = icmp ne ptr null, %v call void @use(i1 %c4) ret void } define void @nonnull_after_branch(i1 %cond1, i1 %cond2, ptr %v) { ; CHECK-LABEL: define void @nonnull_after_branch( ; CHECK-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]], ptr [[V:%.*]]) { ; CHECK-NEXT: [[C1:%.*]] = icmp eq ptr [[V]], null ; CHECK-NEXT: call void @use(i1 [[C1]]) ; CHECK-NEXT: [[C2:%.*]] = icmp ne ptr [[V]], null ; CHECK-NEXT: call void @use(i1 [[C2]]) ; CHECK-NEXT: [[C3:%.*]] = icmp eq ptr null, [[V]] ; CHECK-NEXT: call void @use(i1 [[C3]]) ; CHECK-NEXT: [[C4:%.*]] = icmp ne ptr null, [[V]] ; CHECK-NEXT: call void @use(i1 [[C4]]) ; CHECK-NEXT: br i1 [[COND1]], label %[[TRUE:.*]], label %[[FALSE1:.*]] ; CHECK: [[TRUE]]: ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[V]]) ] ; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: br i1 [[COND2]], label %[[TRUE2:.*]], label %[[FALSE:.*]] ; CHECK: [[TRUE2]]: ; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: ret void ; CHECK: [[FALSE]]: ; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: ret void ; CHECK: [[FALSE1]]: ; CHECK-NEXT: [[CF1:%.*]] = icmp eq ptr [[V]], null ; CHECK-NEXT: call void @use(i1 [[CF1]]) ; CHECK-NEXT: [[CF2:%.*]] = icmp ne ptr [[V]], null ; CHECK-NEXT: call void @use(i1 [[CF2]]) ; CHECK-NEXT: [[CF3:%.*]] = icmp eq ptr null, [[V]] ; CHECK-NEXT: call void @use(i1 [[CF3]]) ; CHECK-NEXT: [[CF4:%.*]] = icmp ne ptr null, [[V]] ; CHECK-NEXT: call void @use(i1 [[CF4]]) ; CHECK-NEXT: ret void ; %c1 = icmp eq ptr %v, null call void @use(i1 %c1) %c2 = icmp ne ptr %v, null call void @use(i1 %c2) %c3 = icmp eq ptr null, %v call void @use(i1 %c3) %c4 = icmp ne ptr null, %v call void @use(i1 %c4) br i1 %cond1, label %true1, label %false1 true1: call void @llvm.assume(i1 true) [ "nonnull"(ptr %v) ] %ct1 = icmp eq ptr %v, null call void @use(i1 %ct1) %ct2 = icmp ne ptr %v, null call void @use(i1 %ct2) %ct3 = icmp eq ptr null, %v call void @use(i1 %ct3) %ct4 = icmp ne ptr null, %v call void @use(i1 %ct4) br i1 %cond2, label %true2, label %false2 true2: %ctt1 = icmp eq ptr %v, null call void @use(i1 %ctt1) %ctt2 = icmp ne ptr %v, null call void @use(i1 %ctt2) %ctt3 = icmp eq ptr null, %v call void @use(i1 %ctt3) %ctt4 = icmp ne ptr null, %v call void @use(i1 %ctt4) ret void false2: %ctf1 = icmp eq ptr %v, null call void @use(i1 %ctf1) %ctf2 = icmp ne ptr %v, null call void @use(i1 %ctf2) %ctf3 = icmp eq ptr null, %v call void @use(i1 %ctf3) %ctf4 = icmp ne ptr null, %v call void @use(i1 %ctf4) ret void false1: %cf1 = icmp eq ptr %v, null call void @use(i1 %cf1) %cf2 = icmp ne ptr %v, null call void @use(i1 %cf2) %cf3 = icmp eq ptr null, %v call void @use(i1 %cf3) %cf4 = icmp ne ptr null, %v call void @use(i1 %cf4) ret void } define void @check_for_constant() { ; CHECK-LABEL: define void @check_for_constant() { ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr null) ] ; CHECK-NEXT: ret void ; call void @llvm.assume(i1 true) [ "nonnull"(ptr null) ] ret void }