1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -sccp -S < %s | FileCheck %s 3 4 5; PR6940 6define double @test1() { 7; CHECK-LABEL: @test1( 8; CHECK-NEXT: [[T:%.*]] = sitofp i32 undef to double 9; CHECK-NEXT: ret double [[T]] 10; 11 %t = sitofp i32 undef to double 12 ret double %t 13} 14 15 16; rdar://7832370 17; Check that lots of stuff doesn't get turned into undef. 18define i32 @test2() nounwind readnone ssp { 19; CHECK-LABEL: @test2( 20; CHECK-NEXT: init: 21; CHECK-NEXT: br label [[CONTROL_OUTER_OUTER:%.*]] 22; CHECK: control.outer.loopexit.us-lcssa: 23; CHECK-NEXT: br label [[CONTROL_OUTER_LOOPEXIT:%.*]] 24; CHECK: control.outer.loopexit: 25; CHECK-NEXT: br label [[CONTROL_OUTER_OUTER_BACKEDGE:%.*]] 26; CHECK: control.outer.outer: 27; CHECK-NEXT: [[SWITCHCOND_0_PH_PH:%.*]] = phi i32 [ 2, [[INIT:%.*]] ], [ 3, [[CONTROL_OUTER_OUTER_BACKEDGE]] ] 28; CHECK-NEXT: [[I_0_PH_PH:%.*]] = phi i32 [ undef, [[INIT]] ], [ [[I_0_PH_PH_BE:%.*]], [[CONTROL_OUTER_OUTER_BACKEDGE]] ] 29; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[I_0_PH_PH]], 0 30; CHECK-NEXT: br i1 [[TMP4]], label [[CONTROL_OUTER_OUTER_SPLIT_US:%.*]], label [[CONTROL_OUTER_OUTER_CONTROL_OUTER_OUTER_SPLIT_CRIT_EDGE:%.*]] 31; CHECK: control.outer.outer.control.outer.outer.split_crit_edge: 32; CHECK-NEXT: br label [[CONTROL_OUTER:%.*]] 33; CHECK: control.outer.outer.split.us: 34; CHECK-NEXT: br label [[CONTROL_OUTER_US:%.*]] 35; CHECK: control.outer.us: 36; CHECK-NEXT: [[A_0_PH_US:%.*]] = phi i32 [ [[SWITCHCOND_0_US:%.*]], [[BB3_US:%.*]] ], [ 4, [[CONTROL_OUTER_OUTER_SPLIT_US]] ] 37; CHECK-NEXT: [[SWITCHCOND_0_PH_US:%.*]] = phi i32 [ [[A_0_PH_US]], [[BB3_US]] ], [ [[SWITCHCOND_0_PH_PH]], [[CONTROL_OUTER_OUTER_SPLIT_US]] ] 38; CHECK-NEXT: br label [[CONTROL_US:%.*]] 39; CHECK: bb3.us: 40; CHECK-NEXT: br label [[CONTROL_OUTER_US]] 41; CHECK: bb0.us: 42; CHECK-NEXT: br label [[CONTROL_US]] 43; CHECK: control.us: 44; CHECK-NEXT: [[SWITCHCOND_0_US]] = phi i32 [ [[A_0_PH_US]], [[BB0_US:%.*]] ], [ [[SWITCHCOND_0_PH_US]], [[CONTROL_OUTER_US]] ] 45; CHECK-NEXT: switch i32 [[SWITCHCOND_0_US]], label [[CONTROL_OUTER_LOOPEXIT_US_LCSSA_US:%.*]] [ 46; CHECK-NEXT: i32 0, label [[BB0_US]] 47; CHECK-NEXT: i32 1, label [[BB1_US_LCSSA_US:%.*]] 48; CHECK-NEXT: i32 3, label [[BB3_US]] 49; CHECK-NEXT: i32 4, label [[BB4_US_LCSSA_US:%.*]] 50; CHECK-NEXT: ] 51; CHECK: control.outer.loopexit.us-lcssa.us: 52; CHECK-NEXT: br label [[CONTROL_OUTER_LOOPEXIT]] 53; CHECK: bb1.us-lcssa.us: 54; CHECK-NEXT: br label [[BB1:%.*]] 55; CHECK: bb4.us-lcssa.us: 56; CHECK-NEXT: br label [[BB4:%.*]] 57; CHECK: control.outer: 58; CHECK-NEXT: [[A_0_PH:%.*]] = phi i32 [ [[NEXTID17:%.*]], [[BB3:%.*]] ], [ 4, [[CONTROL_OUTER_OUTER_CONTROL_OUTER_OUTER_SPLIT_CRIT_EDGE]] ] 59; CHECK-NEXT: [[SWITCHCOND_0_PH:%.*]] = phi i32 [ 0, [[BB3]] ], [ [[SWITCHCOND_0_PH_PH]], [[CONTROL_OUTER_OUTER_CONTROL_OUTER_OUTER_SPLIT_CRIT_EDGE]] ] 60; CHECK-NEXT: br label [[CONTROL:%.*]] 61; CHECK: control: 62; CHECK-NEXT: [[SWITCHCOND_0:%.*]] = phi i32 [ [[A_0_PH]], [[BB0:%.*]] ], [ [[SWITCHCOND_0_PH]], [[CONTROL_OUTER]] ] 63; CHECK-NEXT: switch i32 [[SWITCHCOND_0]], label [[CONTROL_OUTER_LOOPEXIT_US_LCSSA:%.*]] [ 64; CHECK-NEXT: i32 0, label [[BB0]] 65; CHECK-NEXT: i32 1, label [[BB1_US_LCSSA:%.*]] 66; CHECK-NEXT: i32 3, label [[BB3]] 67; CHECK-NEXT: i32 4, label [[BB4_US_LCSSA:%.*]] 68; CHECK-NEXT: ] 69; CHECK: bb4.us-lcssa: 70; CHECK-NEXT: br label [[BB4]] 71; CHECK: bb4: 72; CHECK-NEXT: br label [[CONTROL_OUTER_OUTER_BACKEDGE]] 73; CHECK: control.outer.outer.backedge: 74; CHECK-NEXT: [[I_0_PH_PH_BE]] = phi i32 [ 1, [[BB4]] ], [ 0, [[CONTROL_OUTER_LOOPEXIT]] ] 75; CHECK-NEXT: br label [[CONTROL_OUTER_OUTER]] 76; CHECK: bb3: 77; CHECK-NEXT: [[NEXTID17]] = add i32 [[SWITCHCOND_0]], -2 78; CHECK-NEXT: br label [[CONTROL_OUTER]] 79; CHECK: bb0: 80; CHECK-NEXT: br label [[CONTROL]] 81; CHECK: bb1.us-lcssa: 82; CHECK-NEXT: br label [[BB1]] 83; CHECK: bb1: 84; CHECK-NEXT: ret i32 0 85; 86init: 87 br label %control.outer.outer 88 89control.outer.loopexit.us-lcssa: ; preds = %control 90 br label %control.outer.loopexit 91 92control.outer.loopexit: ; preds = %control.outer.loopexit.us-lcssa.us, %control.outer.loopexit.us-lcssa 93 br label %control.outer.outer.backedge 94 95control.outer.outer: ; preds = %control.outer.outer.backedge, %init 96 %switchCond.0.ph.ph = phi i32 [ 2, %init ], [ 3, %control.outer.outer.backedge ] ; <i32> [#uses=2] 97 %i.0.ph.ph = phi i32 [ undef, %init ], [ %i.0.ph.ph.be, %control.outer.outer.backedge ] ; <i32> [#uses=1] 98 %tmp4 = icmp eq i32 %i.0.ph.ph, 0 ; <i1> [#uses=1] 99 br i1 %tmp4, label %control.outer.outer.split.us, label %control.outer.outer.control.outer.outer.split_crit_edge 100 101control.outer.outer.control.outer.outer.split_crit_edge: ; preds = %control.outer.outer 102 br label %control.outer 103 104control.outer.outer.split.us: ; preds = %control.outer.outer 105 br label %control.outer.us 106 107control.outer.us: ; preds = %bb3.us, %control.outer.outer.split.us 108 %A.0.ph.us = phi i32 [ %switchCond.0.us, %bb3.us ], [ 4, %control.outer.outer.split.us ] ; <i32> [#uses=2] 109 %switchCond.0.ph.us = phi i32 [ %A.0.ph.us, %bb3.us ], [ %switchCond.0.ph.ph, %control.outer.outer.split.us ] ; <i32> [#uses=1] 110 br label %control.us 111 112bb3.us: ; preds = %control.us 113 br label %control.outer.us 114 115bb0.us: ; preds = %control.us 116 br label %control.us 117 118control.us: ; preds = %bb0.us, %control.outer.us 119 %switchCond.0.us = phi i32 [ %A.0.ph.us, %bb0.us ], [ %switchCond.0.ph.us, %control.outer.us ] ; <i32> [#uses=2] 120 switch i32 %switchCond.0.us, label %control.outer.loopexit.us-lcssa.us [ 121 i32 0, label %bb0.us 122 i32 1, label %bb1.us-lcssa.us 123 i32 3, label %bb3.us 124 i32 4, label %bb4.us-lcssa.us 125 ] 126 127control.outer.loopexit.us-lcssa.us: ; preds = %control.us 128 br label %control.outer.loopexit 129 130bb1.us-lcssa.us: ; preds = %control.us 131 br label %bb1 132 133bb4.us-lcssa.us: ; preds = %control.us 134 br label %bb4 135 136control.outer: ; preds = %bb3, %control.outer.outer.control.outer.outer.split_crit_edge 137 %A.0.ph = phi i32 [ %nextId17, %bb3 ], [ 4, %control.outer.outer.control.outer.outer.split_crit_edge ] ; <i32> [#uses=1] 138 %switchCond.0.ph = phi i32 [ 0, %bb3 ], [ %switchCond.0.ph.ph, %control.outer.outer.control.outer.outer.split_crit_edge ] ; <i32> [#uses=1] 139 br label %control 140 141control: ; preds = %bb0, %control.outer 142 %switchCond.0 = phi i32 [ %A.0.ph, %bb0 ], [ %switchCond.0.ph, %control.outer ] ; <i32> [#uses=2] 143 switch i32 %switchCond.0, label %control.outer.loopexit.us-lcssa [ 144 i32 0, label %bb0 145 i32 1, label %bb1.us-lcssa 146 i32 3, label %bb3 147 i32 4, label %bb4.us-lcssa 148 ] 149 150bb4.us-lcssa: ; preds = %control 151 br label %bb4 152 153bb4: ; preds = %bb4.us-lcssa, %bb4.us-lcssa.us 154 br label %control.outer.outer.backedge 155 156control.outer.outer.backedge: ; preds = %bb4, %control.outer.loopexit 157 %i.0.ph.ph.be = phi i32 [ 1, %bb4 ], [ 0, %control.outer.loopexit ] ; <i32> [#uses=1] 158 br label %control.outer.outer 159 160bb3: ; preds = %control 161 %nextId17 = add i32 %switchCond.0, -2 ; <i32> [#uses=1] 162 br label %control.outer 163 164bb0: ; preds = %control 165 br label %control 166 167bb1.us-lcssa: ; preds = %control 168 br label %bb1 169 170bb1: ; preds = %bb1.us-lcssa, %bb1.us-lcssa.us 171 ret i32 0 172} 173 174; Make sure SCCP honors the xor "idiom" 175; rdar://9956541 176define i32 @test3() { 177; CHECK-LABEL: @test3( 178; CHECK-NEXT: [[T:%.*]] = xor i32 undef, undef 179; CHECK-NEXT: ret i32 [[T]] 180; 181 %t = xor i32 undef, undef 182 ret i32 %t 183} 184 185; Be conservative with FP ops 186define double @test4(double %x) { 187; CHECK-LABEL: @test4( 188; CHECK-NEXT: [[T:%.*]] = fadd double [[X:%.*]], undef 189; CHECK-NEXT: ret double [[T]] 190; 191 %t = fadd double %x, undef 192 ret double %t 193} 194 195; Make sure casts produce a possible value 196define i32 @test5() { 197; CHECK-LABEL: @test5( 198; CHECK-NEXT: [[T:%.*]] = sext i8 undef to i32 199; CHECK-NEXT: ret i32 [[T]] 200; 201 %t = sext i8 undef to i32 202 ret i32 %t 203} 204 205; Make sure ashr produces a possible value 206define i32 @test6() { 207; CHECK-LABEL: @test6( 208; CHECK-NEXT: [[T:%.*]] = ashr i32 undef, 31 209; CHECK-NEXT: ret i32 [[T]] 210; 211 %t = ashr i32 undef, 31 212 ret i32 %t 213} 214 215; Make sure lshr produces a possible value 216define i32 @test7() { 217; CHECK-LABEL: @test7( 218; CHECK-NEXT: [[T:%.*]] = lshr i32 undef, 31 219; CHECK-NEXT: ret i32 [[T]] 220; 221 %t = lshr i32 undef, 31 222 ret i32 %t 223} 224 225; icmp eq with undef simplifies to undef 226define i1 @test8() { 227; CHECK-LABEL: @test8( 228; CHECK-NEXT: [[T:%.*]] = icmp eq i32 undef, -1 229; CHECK-NEXT: ret i1 [[T]] 230; 231 %t = icmp eq i32 undef, -1 232 ret i1 %t 233} 234 235; Make sure we don't conclude that relational comparisons simplify to undef 236define i1 @test9() { 237; CHECK-LABEL: @test9( 238; CHECK-NEXT: [[T:%.*]] = icmp ugt i32 undef, -1 239; CHECK-NEXT: ret i1 [[T]] 240; 241 %t = icmp ugt i32 undef, -1 242 ret i1 %t 243} 244 245; Make sure we handle extractvalue 246define i64 @test10() { 247; CHECK-LABEL: @test10( 248; CHECK-NEXT: entry: 249; CHECK-NEXT: [[E:%.*]] = extractvalue { i64, i64 } undef, 1 250; CHECK-NEXT: ret i64 [[E]] 251; 252entry: 253 %e = extractvalue { i64, i64 } undef, 1 254 ret i64 %e 255} 256 257@GV = common global i32 0, align 4 258 259define i32 @test11(i1 %tobool) { 260; CHECK-LABEL: @test11( 261; CHECK-NEXT: entry: 262; CHECK-NEXT: [[SHR4:%.*]] = ashr i32 undef, zext (i1 icmp eq (i32* bitcast (i32 (i1)* @test11 to i32*), i32* @GV) to i32) 263; CHECK-NEXT: ret i32 [[SHR4]] 264; 265entry: 266 %shr4 = ashr i32 undef, zext (i1 icmp eq (i32* bitcast (i32 (i1)* @test11 to i32*), i32* @GV) to i32) 267 ret i32 %shr4 268} 269 270; Test unary ops 271define double @test12(double %x) { 272; CHECK-LABEL: @test12( 273; CHECK-NEXT: [[T:%.*]] = fneg double undef 274; CHECK-NEXT: ret double [[T]] 275; 276 %t = fneg double undef 277 ret double %t 278} 279