1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4define i1 @test_eq(i1 %cond) { 5; CHECK-LABEL: @test_eq( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 8; CHECK: if.true: 9; CHECK-NEXT: br label [[MERGE:%.*]] 10; CHECK: if.false: 11; CHECK-NEXT: br label [[MERGE]] 12; CHECK: merge: 13; CHECK-NEXT: br label [[EXIT:%.*]] 14; CHECK: exit: 15; CHECK-NEXT: [[COMPARE:%.*]] = xor i1 [[COND]], true 16; CHECK-NEXT: ret i1 [[COMPARE]] 17; 18entry: 19 br i1 %cond, label %if.true, label %if.false 20 21if.true: 22 br label %merge 23 24if.false: 25 br label %merge 26 27merge: 28 %phi = phi i32 [123, %if.true], [456, %if.false] 29 br label %exit 30 31exit: 32 %compare = icmp eq i32 %phi, 456 33 ret i1 %compare 34} 35 36define i1 @test_slt(i1 %cond) { 37; CHECK-LABEL: @test_slt( 38; CHECK-NEXT: entry: 39; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 40; CHECK: if.true: 41; CHECK-NEXT: br label [[MERGE:%.*]] 42; CHECK: if.false: 43; CHECK-NEXT: br label [[MERGE]] 44; CHECK: merge: 45; CHECK-NEXT: br label [[EXIT:%.*]] 46; CHECK: exit: 47; CHECK-NEXT: ret i1 [[COND]] 48; 49entry: 50 br i1 %cond, label %if.true, label %if.false 51 52if.true: 53 br label %merge 54 55if.false: 56 br label %merge 57 58merge: 59 %phi = phi i32 [123, %if.true], [456, %if.false] 60 br label %exit 61 62exit: 63 %compare = icmp slt i32 %phi, 456 64 ret i1 %compare 65} 66 67define i1 @test_sle(i1 %cond) { 68; CHECK-LABEL: @test_sle( 69; CHECK-NEXT: entry: 70; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 71; CHECK: if.true: 72; CHECK-NEXT: br label [[MERGE:%.*]] 73; CHECK: if.false: 74; CHECK-NEXT: br label [[MERGE]] 75; CHECK: merge: 76; CHECK-NEXT: br label [[EXIT:%.*]] 77; CHECK: exit: 78; CHECK-NEXT: ret i1 true 79; 80entry: 81 br i1 %cond, label %if.true, label %if.false 82 83if.true: 84 br label %merge 85 86if.false: 87 br label %merge 88 89merge: 90 %phi = phi i32 [123, %if.true], [456, %if.false] 91 br label %exit 92 93exit: 94 %compare = icmp sle i32 %phi, 456 95 ret i1 %compare 96} 97 98define i1 @test_ne(i1 %cond) { 99; CHECK-LABEL: @test_ne( 100; CHECK-NEXT: entry: 101; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 102; CHECK: if.true: 103; CHECK-NEXT: br label [[MERGE:%.*]] 104; CHECK: if.false: 105; CHECK-NEXT: br label [[MERGE]] 106; CHECK: merge: 107; CHECK-NEXT: br label [[EXIT:%.*]] 108; CHECK: exit: 109; CHECK-NEXT: ret i1 [[COND]] 110; 111entry: 112 br i1 %cond, label %if.true, label %if.false 113 114if.true: 115 br label %merge 116 117if.false: 118 br label %merge 119 120merge: 121 %phi = phi i32 [123, %if.true], [456, %if.false] 122 br label %exit 123 124exit: 125 %compare = icmp ne i32 %phi, 456 126 ret i1 %compare 127} 128 129define i1 @test_ne_undef(i1 %cond) { 130; CHECK-LABEL: @test_ne_undef( 131; CHECK-NEXT: entry: 132; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 133; CHECK: if.true: 134; CHECK-NEXT: br label [[MERGE:%.*]] 135; CHECK: if.false: 136; CHECK-NEXT: br label [[MERGE]] 137; CHECK: merge: 138; CHECK-NEXT: br label [[EXIT:%.*]] 139; CHECK: exit: 140; CHECK-NEXT: ret i1 false 141; 142entry: 143 br i1 %cond, label %if.true, label %if.false 144 145if.true: 146 br label %merge 147 148if.false: 149 br label %merge 150 151merge: 152 %phi = phi i32 [undef, %if.true], [456, %if.false] 153 br label %exit 154 155exit: 156 %compare = icmp ne i32 %phi, 456 157 ret i1 %compare 158} 159 160define <2 x i1> @test_ne_int_vector(i1 %cond) { 161; CHECK-LABEL: @test_ne_int_vector( 162; CHECK-NEXT: entry: 163; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 164; CHECK: if.true: 165; CHECK-NEXT: br label [[MERGE:%.*]] 166; CHECK: if.false: 167; CHECK-NEXT: br label [[MERGE]] 168; CHECK: merge: 169; CHECK-NEXT: [[COMPARE:%.*]] = phi <2 x i1> [ <i1 false, i1 true>, [[IF_TRUE]] ], [ <i1 true, i1 false>, [[IF_FALSE]] ] 170; CHECK-NEXT: br label [[EXIT:%.*]] 171; CHECK: exit: 172; CHECK-NEXT: ret <2 x i1> [[COMPARE]] 173; 174entry: 175 br i1 %cond, label %if.true, label %if.false 176 177if.true: 178 br label %merge 179 180if.false: 181 br label %merge 182 183merge: 184 %phi = phi <2 x i32> [<i32 123, i32 123>, %if.true], [<i32 456, i32 456>, %if.false] 185 br label %exit 186 187exit: 188 %compare = icmp ne <2 x i32> %phi, <i32 123, i32 456> 189 ret <2 x i1> %compare 190} 191 192; TODO: We can also constant-fold this comparison for floats. 193define i1 @test_ne_float(i1 %cond) { 194; CHECK-LABEL: @test_ne_float( 195; CHECK-NEXT: entry: 196; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 197; CHECK: if.true: 198; CHECK-NEXT: br label [[MERGE:%.*]] 199; CHECK: if.false: 200; CHECK-NEXT: br label [[MERGE]] 201; CHECK: merge: 202; CHECK-NEXT: br label [[EXIT:%.*]] 203; CHECK: exit: 204; CHECK-NEXT: ret i1 [[COND]] 205; 206entry: 207 br i1 %cond, label %if.true, label %if.false 208 209if.true: 210 br label %merge 211 212if.false: 213 br label %merge 214 215merge: 216 %phi = phi float [1.0, %if.true], [1.25, %if.false] 217 br label %exit 218 219exit: 220 %compare = fcmp one float %phi, 1.25 221 ret i1 %compare 222} 223 224define i1 @test_ne_float_undef(i1 %cond) { 225; CHECK-LABEL: @test_ne_float_undef( 226; CHECK-NEXT: entry: 227; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 228; CHECK: if.true: 229; CHECK-NEXT: br label [[MERGE:%.*]] 230; CHECK: if.false: 231; CHECK-NEXT: br label [[MERGE]] 232; CHECK: merge: 233; CHECK-NEXT: br label [[EXIT:%.*]] 234; CHECK: exit: 235; CHECK-NEXT: ret i1 true 236; 237entry: 238 br i1 %cond, label %if.true, label %if.false 239 240if.true: 241 br label %merge 242 243if.false: 244 br label %merge 245 246merge: 247 %phi = phi float [1.0, %if.true], [undef, %if.false] 248 br label %exit 249 250exit: 251 %compare = fcmp one float %phi, 1.25 252 ret i1 %compare 253} 254 255define <2 x i1> @test_ne_float_vector(i1 %cond) { 256; CHECK-LABEL: @test_ne_float_vector( 257; CHECK-NEXT: entry: 258; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 259; CHECK: if.true: 260; CHECK-NEXT: br label [[MERGE:%.*]] 261; CHECK: if.false: 262; CHECK-NEXT: br label [[MERGE]] 263; CHECK: merge: 264; CHECK-NEXT: [[PHI:%.*]] = phi <2 x i1> [ <i1 false, i1 true>, [[IF_TRUE]] ], [ <i1 true, i1 false>, [[IF_FALSE]] ] 265; CHECK-NEXT: br label [[EXIT:%.*]] 266; CHECK: exit: 267; CHECK-NEXT: ret <2 x i1> [[PHI]] 268; 269entry: 270 br i1 %cond, label %if.true, label %if.false 271 272if.true: 273 br label %merge 274 275if.false: 276 br label %merge 277 278merge: 279 %phi = phi <2 x float> [<float 123.25, float 123.25>, %if.true], [<float 456.25, float 456.25>, %if.false] 280 br label %exit 281 282exit: 283 %compare = fcmp one <2 x float> %phi, <float 123.25, float 456.25> 284 ret <2 x i1> %compare 285} 286