1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=ipsccp -S %s | FileCheck %s 3 4@g = global i64 0 5declare void @use(i1) 6 7define i1 @freeze_undef_i1() { 8; CHECK-LABEL: @freeze_undef_i1( 9; CHECK-NEXT: [[FR:%.*]] = freeze i1 undef 10; CHECK-NEXT: ret i1 [[FR]] 11; 12 %fr = freeze i1 undef 13 ret i1 %fr 14} 15 16define ptr @freeze_undef_ptr() { 17; CHECK-LABEL: @freeze_undef_ptr( 18; CHECK-NEXT: [[FR:%.*]] = freeze ptr undef 19; CHECK-NEXT: ret ptr [[FR]] 20; 21 %fr = freeze ptr undef 22 ret ptr %fr 23} 24 25define float @freeze_undef_float() { 26; CHECK-LABEL: @freeze_undef_float( 27; CHECK-NEXT: [[FR:%.*]] = freeze float undef 28; CHECK-NEXT: ret float [[FR]] 29; 30 %fr = freeze float undef 31 ret float %fr 32} 33 34define <2 x i32> @freeze_undef_vector() { 35; CHECK-LABEL: @freeze_undef_vector( 36; CHECK-NEXT: [[FR:%.*]] = freeze <2 x i32> undef 37; CHECK-NEXT: ret <2 x i32> [[FR]] 38; 39 %fr = freeze <2 x i32> undef 40 ret <2 x i32> %fr 41} 42 43define i1 @freeze_const_i1() { 44; CHECK-LABEL: @freeze_const_i1( 45; CHECK-NEXT: ret i1 true 46; 47 %fr = freeze i1 1 48 ret i1 %fr 49} 50 51define ptr @freeze_const_ptr() { 52; CHECK-LABEL: @freeze_const_ptr( 53; CHECK-NEXT: ret ptr inttoptr (i32 256 to ptr) 54; 55 %fr = freeze ptr inttoptr (i32 256 to ptr) 56 ret ptr %fr 57} 58 59define float @freeze_const_float() { 60; CHECK-LABEL: @freeze_const_float( 61; CHECK-NEXT: ret float 2.500000e-01 62; 63 %fr = freeze float 2.500000e-01 64 ret float %fr 65} 66 67define <2 x i32> @freeze_const_vector() { 68; CHECK-LABEL: @freeze_const_vector( 69; CHECK-NEXT: ret <2 x i32> <i32 1, i32 2> 70; 71 %fr = freeze <2 x i32> <i32 1, i32 2> 72 ret <2 x i32> %fr 73} 74 75; make sure we don't constant-propagate values that could potentially be poison 76define i64 @maybe_poison() { 77; CHECK-LABEL: @maybe_poison( 78; CHECK-NEXT: [[FR:%.*]] = freeze i64 add nuw (i64 ptrtoint (ptr @g to i64), i64 123) 79; CHECK-NEXT: ret i64 [[FR]] 80; 81 %fr = freeze i64 add nuw (i64 ptrtoint (ptr @g to i64), i64 123) 82 ret i64 %fr 83} 84 85define {i64, i64} @freeze_struct({i64, i64} %s) { 86; CHECK-LABEL: @freeze_struct( 87; CHECK-NEXT: [[FR:%.*]] = freeze { i64, i64 } [[S:%.*]] 88; CHECK-NEXT: ret { i64, i64 } [[FR]] 89; 90 %fr = freeze {i64, i64} %s 91 ret {i64, i64} %fr 92} 93 94define i1 @propagate_range_from_and_through_freeze(i32 %x, i32 %y) { 95; CHECK-LABEL: @propagate_range_from_and_through_freeze( 96; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3 97; CHECK-NEXT: [[AND_FR:%.*]] = freeze i32 [[AND]] 98; CHECK-NEXT: [[F_1:%.*]] = icmp eq i32 [[AND_FR]], 100 99; CHECK-NEXT: call void @use(i1 [[F_1]]) 100; CHECK-NEXT: [[T_1:%.*]] = icmp ule i32 [[AND_FR]], 3 101; CHECK-NEXT: call void @use(i1 [[T_1]]) 102; CHECK-NEXT: [[F_2:%.*]] = icmp ugt i32 [[AND_FR]], 3 103; CHECK-NEXT: call void @use(i1 [[F_2]]) 104; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[AND_FR]], [[Y:%.*]] 105; CHECK-NEXT: call void @use(i1 [[C_1]]) 106; CHECK-NEXT: [[R_1:%.*]] = xor i1 [[T_1]], [[F_1]] 107; CHECK-NEXT: [[R_2:%.*]] = xor i1 [[R_1]], [[F_2]] 108; CHECK-NEXT: [[R_3:%.*]] = xor i1 [[R_2]], [[C_1]] 109; CHECK-NEXT: ret i1 [[R_3]] 110; 111 %and = and i32 %x, 3 112 %and.fr = freeze i32 %and 113 %f.1 = icmp eq i32 %and.fr, 100 114 call void @use(i1 %f.1) 115 %t.1 = icmp ule i32 %and.fr, 3 116 call void @use(i1 %t.1) 117 %f.2 = icmp ugt i32 %and.fr, 3 118 call void @use(i1 %f.2) 119 %c.1 = icmp eq i32 %and.fr, %y 120 call void @use(i1 %c.1) 121 %r.1 = xor i1 %t.1, %f.1 122 %r.2 = xor i1 %r.1, %f.2 123 %r.3 = xor i1 %r.2, %c.1 124 ret i1 %r.3 125} 126 127define i1 @range_from_phi_with_undef(i1 %c.1, i1 %c.2) { 128; CHECK-LABEL: @range_from_phi_with_undef( 129; CHECK-NEXT: br i1 [[C_1:%.*]], label [[TRUE_1:%.*]], label [[FALSE:%.*]] 130; CHECK: true.1: 131; CHECK-NEXT: br i1 [[C_2:%.*]], label [[TRUE_2:%.*]], label [[EXIT:%.*]] 132; CHECK: true.2: 133; CHECK-NEXT: br label [[EXIT]] 134; CHECK: false: 135; CHECK-NEXT: br label [[EXIT]] 136; CHECK: exit: 137; CHECK-NEXT: [[P:%.*]] = phi i32 [ 10, [[TRUE_1]] ], [ 20, [[TRUE_2]] ], [ undef, [[FALSE]] ] 138; CHECK-NEXT: [[P_FR:%.*]] = freeze i32 [[P]] 139; CHECK-NEXT: [[T_1:%.*]] = icmp ule i32 [[P_FR]], 20 140; CHECK-NEXT: [[T_2:%.*]] = icmp uge i32 [[P_FR]], 10 141; CHECK-NEXT: [[RES:%.*]] = xor i1 [[T_1]], [[T_2]] 142; CHECK-NEXT: ret i1 [[RES]] 143; 144 br i1 %c.1, label %true.1, label %false 145 146true.1: 147 br i1 %c.2, label %true.2, label %exit 148 149true.2: 150 br label %exit 151 152false: 153 br label %exit 154 155exit: 156 %p = phi i32 [ 10, %true.1 ], [ 20, %true.2], [ undef, %false ] 157 %p.fr = freeze i32 %p 158 %t.1 = icmp ule i32 %p.fr, 20 159 %t.2 = icmp uge i32 %p.fr, 10 160 %res = xor i1 %t.1, %t.2 161 ret i1 %res 162} 163 164define i32 @propagate_info_from_predicate_through_freeze(i32 %x) { 165; CHECK-LABEL: @propagate_info_from_predicate_through_freeze( 166; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 10 167; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X]] 168; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 169; CHECK: then: 170; CHECK-NEXT: [[ADD_1:%.*]] = add i32 [[X_FR]], 10 171; CHECK-NEXT: [[ADD_2:%.*]] = add i32 [[X_FR]], 1 172; CHECK-NEXT: ret i32 [[ADD_2]] 173; CHECK: else: 174; CHECK-NEXT: [[ADD_3:%.*]] = add i32 [[X_FR]], 1 175; CHECK-NEXT: ret i32 [[ADD_3]] 176; 177 %cmp = icmp eq i32 %x, 10 178 %x.fr = freeze i32 %x 179 br i1 %cmp, label %then, label %else 180 181then: 182 %add.1 = add i32 %x.fr, %x 183 %add.2 = add i32 %x.fr, 1 184 ret i32 %add.2 185 186else: 187 %add.3 = add i32 %x.fr, 1 188 ret i32 %add.3 189} 190