1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt -S -passes=instcombine %s | FileCheck %s 3 4declare void @use(i1) 5 6define i1 @test_and_olt(float %x) { 7; CHECK-LABEL: define i1 @test_and_olt( 8; CHECK-SAME: float [[X:%.*]]) { 9; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]]) 10; CHECK-NEXT: [[COND:%.*]] = fcmp olt float [[TMP1]], 0x3C00000000000000 11; CHECK-NEXT: ret i1 [[COND]] 12; 13 %cmp1 = fcmp olt float %x, 0x3C00000000000000 14 %cmp2 = fcmp ogt float %x, 0xBC00000000000000 15 %cond = and i1 %cmp1, %cmp2 16 ret i1 %cond 17} 18 19define i1 @test_and_ole(float %x) { 20; CHECK-LABEL: define i1 @test_and_ole( 21; CHECK-SAME: float [[X:%.*]]) { 22; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]]) 23; CHECK-NEXT: [[COND:%.*]] = fcmp ole float [[TMP1]], 0x3C00000000000000 24; CHECK-NEXT: ret i1 [[COND]] 25; 26 %cmp1 = fcmp ole float %x, 0x3C00000000000000 27 %cmp2 = fcmp oge float %x, 0xBC00000000000000 28 %cond = and i1 %cmp1, %cmp2 29 ret i1 %cond 30} 31 32define i1 @test_or_ogt(float %x) { 33; CHECK-LABEL: define i1 @test_or_ogt( 34; CHECK-SAME: float [[X:%.*]]) { 35; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]]) 36; CHECK-NEXT: [[COND:%.*]] = fcmp ogt float [[TMP1]], 0x3C00000000000000 37; CHECK-NEXT: ret i1 [[COND]] 38; 39 %cmp1 = fcmp ogt float %x, 0x3C00000000000000 40 %cmp2 = fcmp olt float %x, 0xBC00000000000000 41 %cond = or i1 %cmp1, %cmp2 42 ret i1 %cond 43} 44 45define i1 @test_or_oge(float %x) { 46; CHECK-LABEL: define i1 @test_or_oge( 47; CHECK-SAME: float [[X:%.*]]) { 48; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]]) 49; CHECK-NEXT: [[COND:%.*]] = fcmp oge float [[TMP1]], 0x3C00000000000000 50; CHECK-NEXT: ret i1 [[COND]] 51; 52 %cmp1 = fcmp oge float %x, 0x3C00000000000000 53 %cmp2 = fcmp ole float %x, 0xBC00000000000000 54 %cond = or i1 %cmp1, %cmp2 55 ret i1 %cond 56} 57 58define i1 @test_and_ult(float %x) { 59; CHECK-LABEL: define i1 @test_and_ult( 60; CHECK-SAME: float [[X:%.*]]) { 61; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]]) 62; CHECK-NEXT: [[COND:%.*]] = fcmp ult float [[TMP1]], 0x3C00000000000000 63; CHECK-NEXT: ret i1 [[COND]] 64; 65 %cmp1 = fcmp ult float %x, 0x3C00000000000000 66 %cmp2 = fcmp ugt float %x, 0xBC00000000000000 67 %cond = and i1 %cmp1, %cmp2 68 ret i1 %cond 69} 70 71define i1 @test_and_ule(float %x) { 72; CHECK-LABEL: define i1 @test_and_ule( 73; CHECK-SAME: float [[X:%.*]]) { 74; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]]) 75; CHECK-NEXT: [[COND:%.*]] = fcmp ule float [[TMP1]], 0x3C00000000000000 76; CHECK-NEXT: ret i1 [[COND]] 77; 78 %cmp1 = fcmp ule float %x, 0x3C00000000000000 79 %cmp2 = fcmp uge float %x, 0xBC00000000000000 80 %cond = and i1 %cmp1, %cmp2 81 ret i1 %cond 82} 83 84define i1 @test_or_ugt(float %x) { 85; CHECK-LABEL: define i1 @test_or_ugt( 86; CHECK-SAME: float [[X:%.*]]) { 87; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]]) 88; CHECK-NEXT: [[COND:%.*]] = fcmp ugt float [[TMP1]], 0x3C00000000000000 89; CHECK-NEXT: ret i1 [[COND]] 90; 91 %cmp1 = fcmp ugt float %x, 0x3C00000000000000 92 %cmp2 = fcmp ult float %x, 0xBC00000000000000 93 %cond = or i1 %cmp1, %cmp2 94 ret i1 %cond 95} 96 97define i1 @test_or_uge(float %x) { 98; CHECK-LABEL: define i1 @test_or_uge( 99; CHECK-SAME: float [[X:%.*]]) { 100; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]]) 101; CHECK-NEXT: [[COND:%.*]] = fcmp uge float [[TMP1]], 0x3C00000000000000 102; CHECK-NEXT: ret i1 [[COND]] 103; 104 %cmp1 = fcmp uge float %x, 0x3C00000000000000 105 %cmp2 = fcmp ule float %x, 0xBC00000000000000 106 %cond = or i1 %cmp1, %cmp2 107 ret i1 %cond 108} 109 110define i1 @test_and_olt_commuted(float %x) { 111; CHECK-LABEL: define i1 @test_and_olt_commuted( 112; CHECK-SAME: float [[X:%.*]]) { 113; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]]) 114; CHECK-NEXT: [[COND:%.*]] = fcmp olt float [[TMP1]], 0x3C00000000000000 115; CHECK-NEXT: ret i1 [[COND]] 116; 117 %cmp1 = fcmp olt float %x, 0x3C00000000000000 118 %cmp2 = fcmp ogt float %x, 0xBC00000000000000 119 %cond = and i1 %cmp2, %cmp1 120 ret i1 %cond 121} 122 123define i1 @test_and_olt_subnormal(float %x) { 124; CHECK-LABEL: define i1 @test_and_olt_subnormal( 125; CHECK-SAME: float [[X:%.*]]) { 126; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]]) 127; CHECK-NEXT: [[COND:%.*]] = fcmp olt float [[TMP1]], 0x36A0000000000000 128; CHECK-NEXT: ret i1 [[COND]] 129; 130 %cmp1 = fcmp olt float %x, 0x36A0000000000000 131 %cmp2 = fcmp ogt float %x, 0xB6A0000000000000 132 %cond = and i1 %cmp1, %cmp2 133 ret i1 %cond 134} 135 136define i1 @test_and_olt_infinity(float %x) { 137; CHECK-LABEL: define i1 @test_and_olt_infinity( 138; CHECK-SAME: float [[X:%.*]]) { 139; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]]) 140; CHECK-NEXT: [[COND:%.*]] = fcmp one float [[TMP1]], 0x7FF0000000000000 141; CHECK-NEXT: ret i1 [[COND]] 142; 143 %cmp1 = fcmp olt float %x, 0x7FF0000000000000 144 %cmp2 = fcmp ogt float %x, 0xFFF0000000000000 145 %cond = and i1 %cmp1, %cmp2 146 ret i1 %cond 147} 148 149define i1 @test_and_olt_zero(float %x) { 150; CHECK-LABEL: define i1 @test_and_olt_zero( 151; CHECK-SAME: float [[X:%.*]]) { 152; CHECK-NEXT: ret i1 false 153; 154 %cmp1 = fcmp olt float %x, 0x0000000000000000 155 %cmp2 = fcmp ogt float %x, 0x8000000000000000 156 %cond = and i1 %cmp1, %cmp2 157 ret i1 %cond 158} 159 160define i1 @test_and_ole_zero(float %x) { 161; CHECK-LABEL: define i1 @test_and_ole_zero( 162; CHECK-SAME: float [[X:%.*]]) { 163; CHECK-NEXT: [[COND:%.*]] = fcmp oeq float [[X]], 0.000000e+00 164; CHECK-NEXT: ret i1 [[COND]] 165; 166 %cmp1 = fcmp ole float %x, 0x0000000000000000 167 %cmp2 = fcmp oge float %x, 0x8000000000000000 168 %cond = and i1 %cmp1, %cmp2 169 ret i1 %cond 170} 171 172define i1 @test_and_olt_logical(float %x) { 173; CHECK-LABEL: define i1 @test_and_olt_logical( 174; CHECK-SAME: float [[X:%.*]]) { 175; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]]) 176; CHECK-NEXT: [[COND:%.*]] = fcmp olt float [[TMP1]], 0x3C00000000000000 177; CHECK-NEXT: ret i1 [[COND]] 178; 179 %cmp1 = fcmp olt float %x, 0x3C00000000000000 180 %cmp2 = fcmp ogt float %x, 0xBC00000000000000 181 %cond = select i1 %cmp1, i1 %cmp2, i1 false 182 ret i1 %cond 183} 184 185define <2 x i1> @test_and_olt_poison(<2 x float> %x) { 186; CHECK-LABEL: define <2 x i1> @test_and_olt_poison( 187; CHECK-SAME: <2 x float> [[X:%.*]]) { 188; CHECK-NEXT: [[TMP1:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X]]) 189; CHECK-NEXT: [[COND:%.*]] = fcmp olt <2 x float> [[TMP1]], splat (float 0x3C00000000000000) 190; CHECK-NEXT: ret <2 x i1> [[COND]] 191; 192 %cmp1 = fcmp olt <2 x float> %x, <float 0x3C00000000000000, float poison> 193 %cmp2 = fcmp ogt <2 x float> %x, <float 0xBC00000000000000, float poison> 194 %cond = and <2 x i1> %cmp1, %cmp2 195 ret <2 x i1> %cond 196} 197 198define i1 @test_and_olt_nan(float %x) { 199; CHECK-LABEL: define i1 @test_and_olt_nan( 200; CHECK-SAME: float [[X:%.*]]) { 201; CHECK-NEXT: ret i1 false 202; 203 %cmp1 = fcmp olt float %x, 0x7FF8000000000000 204 %cmp2 = fcmp ogt float %x, 0xFFF8000000000000 205 %cond = and i1 %cmp1, %cmp2 206 ret i1 %cond 207} 208 209define i1 @test_and_ult_nan(float %x) { 210; CHECK-LABEL: define i1 @test_and_ult_nan( 211; CHECK-SAME: float [[X:%.*]]) { 212; CHECK-NEXT: ret i1 true 213; 214 %cmp1 = fcmp ult float %x, 0x7FF0000020000000 215 %cmp2 = fcmp ugt float %x, 0xFFF0000020000000 216 %cond = and i1 %cmp1, %cmp2 217 ret i1 %cond 218} 219 220define i1 @test_or_ogt_nan(float %x) { 221; CHECK-LABEL: define i1 @test_or_ogt_nan( 222; CHECK-SAME: float [[X:%.*]]) { 223; CHECK-NEXT: ret i1 false 224; 225 %cmp1 = fcmp ogt float %x, 0x7FF0000020000000 226 %cmp2 = fcmp olt float %x, 0xFFF0000020000000 227 %cond = or i1 %cmp1, %cmp2 228 ret i1 %cond 229} 230 231define i1 @test_or_ugt_nan(float %x) { 232; CHECK-LABEL: define i1 @test_or_ugt_nan( 233; CHECK-SAME: float [[X:%.*]]) { 234; CHECK-NEXT: ret i1 true 235; 236 %cmp1 = fcmp ugt float %x, 0x7FF0000020000000 237 %cmp2 = fcmp ult float %x, 0xFFF0000020000000 238 %cond = or i1 %cmp1, %cmp2 239 ret i1 %cond 240} 241 242define i1 @test_and_ogt(float %x) { 243; CHECK-LABEL: define i1 @test_and_ogt( 244; CHECK-SAME: float [[X:%.*]]) { 245; CHECK-NEXT: ret i1 false 246; 247 %cmp1 = fcmp ogt float %x, 0x3C00000000000000 248 %cmp2 = fcmp olt float %x, 0xBC00000000000000 249 %cond = and i1 %cmp1, %cmp2 250 ret i1 %cond 251} 252 253define i1 @test_or_olt(float %x) { 254; CHECK-LABEL: define i1 @test_or_olt( 255; CHECK-SAME: float [[X:%.*]]) { 256; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]]) 257; CHECK-NEXT: [[COND:%.*]] = fcmp ogt float [[TMP1]], 0xBC00000000000000 258; CHECK-NEXT: ret i1 [[COND]] 259; 260 %cmp1 = fcmp olt float %x, 0x3C00000000000000 261 %cmp2 = fcmp ogt float %x, 0xBC00000000000000 262 %cond = or i1 %cmp1, %cmp2 263 ret i1 %cond 264} 265 266; Negative tests 267 268define i1 @test_and_olt_multiuse(float %x) { 269; CHECK-LABEL: define i1 @test_and_olt_multiuse( 270; CHECK-SAME: float [[X:%.*]]) { 271; CHECK-NEXT: [[CMP1:%.*]] = fcmp olt float [[X]], 0x3C00000000000000 272; CHECK-NEXT: call void @use(i1 [[CMP1]]) 273; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt float [[X]], 0xBC00000000000000 274; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP1]], [[CMP2]] 275; CHECK-NEXT: ret i1 [[COND]] 276; 277 %cmp1 = fcmp olt float %x, 0x3C00000000000000 278 call void @use(i1 %cmp1) 279 %cmp2 = fcmp ogt float %x, 0xBC00000000000000 280 %cond = and i1 %cmp1, %cmp2 281 ret i1 %cond 282} 283 284define i1 @test_and_olt_mismatched_lhs(float %x, float %y) { 285; CHECK-LABEL: define i1 @test_and_olt_mismatched_lhs( 286; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) { 287; CHECK-NEXT: [[CMP1:%.*]] = fcmp olt float [[X]], 0x3C00000000000000 288; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt float [[Y]], 0xBC00000000000000 289; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP1]], [[CMP2]] 290; CHECK-NEXT: ret i1 [[COND]] 291; 292 %cmp1 = fcmp olt float %x, 0x3C00000000000000 293 %cmp2 = fcmp ogt float %y, 0xBC00000000000000 294 %cond = and i1 %cmp1, %cmp2 295 ret i1 %cond 296} 297 298define i1 @test_and_olt_same_sign(float %x) { 299; CHECK-LABEL: define i1 @test_and_olt_same_sign( 300; CHECK-SAME: float [[X:%.*]]) { 301; CHECK-NEXT: ret i1 false 302; 303 %cmp1 = fcmp olt float %x, 0x3C00000000000000 304 %cmp2 = fcmp ogt float %x, 0x3C00000000000000 305 %cond = and i1 %cmp1, %cmp2 306 ret i1 %cond 307} 308 309define i1 @test_and_olt_mismatched_mag(float %x) { 310; CHECK-LABEL: define i1 @test_and_olt_mismatched_mag( 311; CHECK-SAME: float [[X:%.*]]) { 312; CHECK-NEXT: [[CMP1:%.*]] = fcmp olt float [[X]], 0x3C80000000000000 313; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt float [[X]], 0xBC00000000000000 314; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP1]], [[CMP2]] 315; CHECK-NEXT: ret i1 [[COND]] 316; 317 %cmp1 = fcmp olt float %x, 0x3C80000000000000 318 %cmp2 = fcmp ogt float %x, 0xBC00000000000000 319 %cond = and i1 %cmp1, %cmp2 320 ret i1 %cond 321} 322 323define i1 @test_and_olt_wrong_pred2(float %x) { 324; CHECK-LABEL: define i1 @test_and_olt_wrong_pred2( 325; CHECK-SAME: float [[X:%.*]]) { 326; CHECK-NEXT: [[CMP1:%.*]] = fcmp olt float [[X]], 0x3C00000000000000 327; CHECK-NEXT: [[CMP2:%.*]] = fcmp oge float [[X]], 0xBC00000000000000 328; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP1]], [[CMP2]] 329; CHECK-NEXT: ret i1 [[COND]] 330; 331 %cmp1 = fcmp olt float %x, 0x3C00000000000000 332 %cmp2 = fcmp oge float %x, 0xBC00000000000000 333 %cond = and i1 %cmp1, %cmp2 334 ret i1 %cond 335} 336 337define i1 @test_and_olt_fmf_propagation(float %x) { 338; CHECK-LABEL: define i1 @test_and_olt_fmf_propagation( 339; CHECK-SAME: float [[X:%.*]]) { 340; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf nsz float @llvm.fabs.f32(float [[X]]) 341; CHECK-NEXT: [[COND:%.*]] = fcmp nnan ninf nsz olt float [[TMP1]], 0x3C00000000000000 342; CHECK-NEXT: ret i1 [[COND]] 343; 344 %cmp1 = fcmp nsz nnan ninf olt float %x, 0x3C00000000000000 345 %cmp2 = fcmp nsz nnan ninf ogt float %x, 0xBC00000000000000 346 %cond = and i1 %cmp1, %cmp2 347 ret i1 %cond 348} 349 350define i1 @test_and_olt_fmf_propagation_union(float %x) { 351; CHECK-LABEL: define i1 @test_and_olt_fmf_propagation_union( 352; CHECK-SAME: float [[X:%.*]]) { 353; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf nsz float @llvm.fabs.f32(float [[X]]) 354; CHECK-NEXT: [[COND:%.*]] = fcmp nnan ninf nsz olt float [[TMP1]], 0x3C00000000000000 355; CHECK-NEXT: ret i1 [[COND]] 356; 357 %cmp1 = fcmp nnan ninf olt float %x, 0x3C00000000000000 358 %cmp2 = fcmp nsz nnan ogt float %x, 0xBC00000000000000 359 %cond = and i1 %cmp1, %cmp2 360 ret i1 %cond 361} 362 363define i1 @test_and_olt_fmf_propagation_union_logical_rhs_poison(float %x) { 364; CHECK-LABEL: define i1 @test_and_olt_fmf_propagation_union_logical_rhs_poison( 365; CHECK-SAME: float [[X:%.*]]) { 366; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]]) 367; CHECK-NEXT: [[COND:%.*]] = fcmp olt float [[TMP1]], 0x3C00000000000000 368; CHECK-NEXT: ret i1 [[COND]] 369; 370 %cmp1 = fcmp ninf olt float %x, 0x3C00000000000000 371 %cmp2 = fcmp ogt float %x, 0xBC00000000000000 372 %cond = select i1 %cmp2, i1 %cmp1, i1 false 373 ret i1 %cond 374} 375 376define i1 @test_and_olt_fmf_propagation_union_logical_lhs_poison(float %x) { 377; CHECK-LABEL: define i1 @test_and_olt_fmf_propagation_union_logical_lhs_poison( 378; CHECK-SAME: float [[X:%.*]]) { 379; CHECK-NEXT: [[TMP1:%.*]] = call ninf float @llvm.fabs.f32(float [[X]]) 380; CHECK-NEXT: [[COND:%.*]] = fcmp ninf olt float [[TMP1]], 0x3C00000000000000 381; CHECK-NEXT: ret i1 [[COND]] 382; 383 %cmp1 = fcmp olt float %x, 0x3C00000000000000 384 %cmp2 = fcmp ninf ogt float %x, 0xBC00000000000000 385 %cond = select i1 %cmp2, i1 %cmp1, i1 false 386 ret i1 %cond 387} 388 389define i1 @test_and_olt_fmf_propagation_union_logical_both_poison(float %x) { 390; CHECK-LABEL: define i1 @test_and_olt_fmf_propagation_union_logical_both_poison( 391; CHECK-SAME: float [[X:%.*]]) { 392; CHECK-NEXT: [[TMP1:%.*]] = call ninf float @llvm.fabs.f32(float [[X]]) 393; CHECK-NEXT: [[COND:%.*]] = fcmp ninf olt float [[TMP1]], 0x3C00000000000000 394; CHECK-NEXT: ret i1 [[COND]] 395; 396 %cmp1 = fcmp ninf olt float %x, 0x3C00000000000000 397 %cmp2 = fcmp ninf ogt float %x, 0xBC00000000000000 398 %cond = select i1 %cmp2, i1 %cmp1, i1 false 399 ret i1 %cond 400} 401