1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S < %s | FileCheck %s 3 4%struct.Counters = type { i64, i64, i64, [8 x i8] } 5 6@m = global i64 3, align 8 7@counters = global %struct.Counters zeroinitializer, align 16 8 9define i32 @align_both_equal() local_unnamed_addr { 10; CHECK-LABEL: @align_both_equal( 11; CHECK-NEXT: entry: 12; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS:%.*]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 13; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 1, i64 1> 14; CHECK-NEXT: store <2 x i64> [[TMP1]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 15; CHECK-NEXT: [[TMP2:%.*]] = load i64, i64* @m, align 8 16; CHECK-NEXT: [[AND:%.*]] = and i64 [[TMP2]], 1 17; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0 18; CHECK-NEXT: [[TMP3:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 2, i64 2> 19; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]] 20; CHECK-NEXT: [[AND4:%.*]] = and i64 [[TMP2]], 2 21; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp eq i64 [[AND4]], 0 22; CHECK-NEXT: [[TMP5:%.*]] = add nsw <2 x i64> [[TMP4]], <i64 1, i64 1> 23; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[TMP4]], <2 x i64> [[TMP5]] 24; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL]], true 25; CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TOBOOL5]], true 26; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]] 27; CHECK-NEXT: br i1 [[TMP8]], label [[TMP9:%.*]], label [[TMP10:%.*]] 28; CHECK: 9: 29; CHECK-NEXT: store <2 x i64> [[SPEC_SELECT]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 30; CHECK-NEXT: br label [[TMP10]] 31; CHECK: 10: 32; CHECK-NEXT: ret i32 0 33; 34entry: 35 %0 = load <2 x i64>, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 36 %1 = add nsw <2 x i64> %0, <i64 1, i64 1> 37 store <2 x i64> %1, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 38 %2 = load i64, i64* @m, align 8 39 %and = and i64 %2, 1 40 %tobool = icmp eq i64 %and, 0 41 br i1 %tobool, label %if.end, label %if.then 42 43if.then: ; preds = %entry 44 %3 = add nsw <2 x i64> %0, <i64 2, i64 2> 45 store <2 x i64> %3, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 46 br label %if.end 47 48if.end: ; preds = %entry, %if.then 49 %4 = phi <2 x i64> [ %1, %entry ], [ %3, %if.then ] 50 %and4 = and i64 %2, 2 51 %tobool5 = icmp eq i64 %and4, 0 52 br i1 %tobool5, label %if.end9, label %if.then6 53 54if.then6: ; preds = %if.end 55 %5 = add nsw <2 x i64> %4, <i64 1, i64 1> 56 store <2 x i64> %5, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 57 br label %if.end9 58 59if.end9: ; preds = %if.end, %if.then6 60 ret i32 0 61} 62 63define i32 @align_not_equal() local_unnamed_addr { 64; CHECK-LABEL: @align_not_equal( 65; CHECK-NEXT: entry: 66; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS:%.*]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 67; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 1, i64 1> 68; CHECK-NEXT: store <2 x i64> [[TMP1]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 69; CHECK-NEXT: [[TMP2:%.*]] = load i64, i64* @m, align 8 70; CHECK-NEXT: [[AND:%.*]] = and i64 [[TMP2]], 1 71; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0 72; CHECK-NEXT: [[TMP3:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 2, i64 2> 73; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]] 74; CHECK-NEXT: [[AND4:%.*]] = and i64 [[TMP2]], 2 75; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp eq i64 [[AND4]], 0 76; CHECK-NEXT: [[TMP5:%.*]] = add nsw <2 x i64> [[TMP4]], <i64 1, i64 1> 77; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[TMP4]], <2 x i64> [[TMP5]] 78; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL]], true 79; CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TOBOOL5]], true 80; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]] 81; CHECK-NEXT: br i1 [[TMP8]], label [[TMP9:%.*]], label [[TMP10:%.*]] 82; CHECK: 9: 83; CHECK-NEXT: store <2 x i64> [[SPEC_SELECT]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 84; CHECK-NEXT: br label [[TMP10]] 85; CHECK: 10: 86; CHECK-NEXT: ret i32 0 87; 88entry: 89 %0 = load <2 x i64>, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 90 %1 = add nsw <2 x i64> %0, <i64 1, i64 1> 91 store <2 x i64> %1, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 92 %2 = load i64, i64* @m, align 8 93 %and = and i64 %2, 1 94 %tobool = icmp eq i64 %and, 0 95 br i1 %tobool, label %if.end, label %if.then 96 97if.then: ; preds = %entry 98 %3 = add nsw <2 x i64> %0, <i64 2, i64 2> 99 store <2 x i64> %3, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 16 100 br label %if.end 101 102if.end: ; preds = %entry, %if.then 103 %4 = phi <2 x i64> [ %1, %entry ], [ %3, %if.then ] 104 %and4 = and i64 %2, 2 105 %tobool5 = icmp eq i64 %and4, 0 106 br i1 %tobool5, label %if.end9, label %if.then6 107 108if.then6: ; preds = %if.end 109 %5 = add nsw <2 x i64> %4, <i64 1, i64 1> 110 store <2 x i64> %5, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 111 br label %if.end9 112 113if.end9: ; preds = %if.end, %if.then6 114 ret i32 0 115} 116 117define i32 @align_single_zero() local_unnamed_addr { 118; CHECK-LABEL: @align_single_zero( 119; CHECK-NEXT: entry: 120; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS:%.*]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 121; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 1, i64 1> 122; CHECK-NEXT: store <2 x i64> [[TMP1]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 123; CHECK-NEXT: [[TMP2:%.*]] = load i64, i64* @m, align 8 124; CHECK-NEXT: [[AND:%.*]] = and i64 [[TMP2]], 1 125; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0 126; CHECK-NEXT: [[TMP3:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 2, i64 2> 127; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]] 128; CHECK-NEXT: [[AND4:%.*]] = and i64 [[TMP2]], 2 129; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp eq i64 [[AND4]], 0 130; CHECK-NEXT: [[TMP5:%.*]] = add nsw <2 x i64> [[TMP4]], <i64 1, i64 1> 131; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[TMP4]], <2 x i64> [[TMP5]] 132; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL]], true 133; CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TOBOOL5]], true 134; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]] 135; CHECK-NEXT: br i1 [[TMP8]], label [[TMP9:%.*]], label [[TMP10:%.*]] 136; CHECK: 9: 137; CHECK-NEXT: store <2 x i64> [[SPEC_SELECT]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 138; CHECK-NEXT: br label [[TMP10]] 139; CHECK: 10: 140; CHECK-NEXT: ret i32 0 141; 142entry: 143 %0 = load <2 x i64>, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 144 %1 = add nsw <2 x i64> %0, <i64 1, i64 1> 145 store <2 x i64> %1, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 146 %2 = load i64, i64* @m, align 8 147 %and = and i64 %2, 1 148 %tobool = icmp eq i64 %and, 0 149 br i1 %tobool, label %if.end, label %if.then 150 151if.then: ; preds = %entry 152 %3 = add nsw <2 x i64> %0, <i64 2, i64 2> 153 store <2 x i64> %3, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*) 154 br label %if.end 155 156if.end: ; preds = %entry, %if.then 157 %4 = phi <2 x i64> [ %1, %entry ], [ %3, %if.then ] 158 %and4 = and i64 %2, 2 159 %tobool5 = icmp eq i64 %and4, 0 160 br i1 %tobool5, label %if.end9, label %if.then6 161 162if.then6: ; preds = %if.end 163 %5 = add nsw <2 x i64> %4, <i64 1, i64 1> 164 store <2 x i64> %5, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 165 br label %if.end9 166 167if.end9: ; preds = %if.end, %if.then6 168 ret i32 0 169} 170 171define i32 @align_single_zero_second_greater_default() local_unnamed_addr { 172; CHECK-LABEL: @align_single_zero_second_greater_default( 173; CHECK-NEXT: entry: 174; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS:%.*]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 175; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 1, i64 1> 176; CHECK-NEXT: store <2 x i64> [[TMP1]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 177; CHECK-NEXT: [[TMP2:%.*]] = load i64, i64* @m, align 8 178; CHECK-NEXT: [[AND:%.*]] = and i64 [[TMP2]], 1 179; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0 180; CHECK-NEXT: [[TMP3:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 2, i64 2> 181; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]] 182; CHECK-NEXT: [[AND4:%.*]] = and i64 [[TMP2]], 2 183; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp eq i64 [[AND4]], 0 184; CHECK-NEXT: [[TMP5:%.*]] = add nsw <2 x i64> [[TMP4]], <i64 1, i64 1> 185; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[TMP4]], <2 x i64> [[TMP5]] 186; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL]], true 187; CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TOBOOL5]], true 188; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]] 189; CHECK-NEXT: br i1 [[TMP8]], label [[TMP9:%.*]], label [[TMP10:%.*]] 190; CHECK: 9: 191; CHECK-NEXT: store <2 x i64> [[SPEC_SELECT]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 16 192; CHECK-NEXT: br label [[TMP10]] 193; CHECK: 10: 194; CHECK-NEXT: ret i32 0 195; 196entry: 197 %0 = load <2 x i64>, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 198 %1 = add nsw <2 x i64> %0, <i64 1, i64 1> 199 store <2 x i64> %1, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 200 %2 = load i64, i64* @m, align 8 201 %and = and i64 %2, 1 202 %tobool = icmp eq i64 %and, 0 203 br i1 %tobool, label %if.end, label %if.then 204 205if.then: ; preds = %entry 206 %3 = add nsw <2 x i64> %0, <i64 2, i64 2> 207 store <2 x i64> %3, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 32 208 br label %if.end 209 210if.end: ; preds = %entry, %if.then 211 %4 = phi <2 x i64> [ %1, %entry ], [ %3, %if.then ] 212 %and4 = and i64 %2, 2 213 %tobool5 = icmp eq i64 %and4, 0 214 br i1 %tobool5, label %if.end9, label %if.then6 215 216if.then6: ; preds = %if.end 217 %5 = add nsw <2 x i64> %4, <i64 1, i64 1> 218 store <2 x i64> %5, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*) 219 br label %if.end9 220 221if.end9: ; preds = %if.end, %if.then6 222 ret i32 0 223} 224 225define i32 @align_both_zero() local_unnamed_addr { 226; CHECK-LABEL: @align_both_zero( 227; CHECK-NEXT: entry: 228; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS:%.*]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 229; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 1, i64 1> 230; CHECK-NEXT: store <2 x i64> [[TMP1]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 231; CHECK-NEXT: [[TMP2:%.*]] = load i64, i64* @m, align 8 232; CHECK-NEXT: [[AND:%.*]] = and i64 [[TMP2]], 1 233; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0 234; CHECK-NEXT: [[TMP3:%.*]] = add nsw <2 x i64> [[TMP0]], <i64 2, i64 2> 235; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TOBOOL]], <2 x i64> [[TMP1]], <2 x i64> [[TMP3]] 236; CHECK-NEXT: [[AND4:%.*]] = and i64 [[TMP2]], 2 237; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp eq i64 [[AND4]], 0 238; CHECK-NEXT: [[TMP5:%.*]] = add nsw <2 x i64> [[TMP4]], <i64 1, i64 1> 239; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL5]], <2 x i64> [[TMP4]], <2 x i64> [[TMP5]] 240; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TOBOOL]], true 241; CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TOBOOL5]], true 242; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]] 243; CHECK-NEXT: br i1 [[TMP8]], label [[TMP9:%.*]], label [[TMP10:%.*]] 244; CHECK: 9: 245; CHECK-NEXT: store <2 x i64> [[SPEC_SELECT]], <2 x i64>* bitcast (i64* getelementptr inbounds ([[STRUCT_COUNTERS]], %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 16 246; CHECK-NEXT: br label [[TMP10]] 247; CHECK: 10: 248; CHECK-NEXT: ret i32 0 249; 250entry: 251 %0 = load <2 x i64>, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 252 %1 = add nsw <2 x i64> %0, <i64 1, i64 1> 253 store <2 x i64> %1, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*), align 8 254 %2 = load i64, i64* @m, align 8 255 %and = and i64 %2, 1 256 %tobool = icmp eq i64 %and, 0 257 br i1 %tobool, label %if.end, label %if.then 258 259if.then: ; preds = %entry 260 %3 = add nsw <2 x i64> %0, <i64 2, i64 2> 261 store <2 x i64> %3, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*) 262 br label %if.end 263 264if.end: ; preds = %entry, %if.then 265 %4 = phi <2 x i64> [ %1, %entry ], [ %3, %if.then ] 266 %and4 = and i64 %2, 2 267 %tobool5 = icmp eq i64 %and4, 0 268 br i1 %tobool5, label %if.end9, label %if.then6 269 270if.then6: ; preds = %if.end 271 %5 = add nsw <2 x i64> %4, <i64 1, i64 1> 272 store <2 x i64> %5, <2 x i64>* bitcast (i64* getelementptr inbounds (%struct.Counters, %struct.Counters* @counters, i64 0, i32 1) to <2 x i64>*) 273 br label %if.end9 274 275if.end9: ; preds = %if.end, %if.then6 276 ret i32 0 277} 278