1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4define float @select_maybe_nan_fadd(i1 %cond, float %A, float %B) { 5; CHECK-LABEL: @select_maybe_nan_fadd( 6; CHECK-NEXT: [[C:%.*]] = fadd float [[A:%.*]], [[B:%.*]] 7; CHECK-NEXT: [[D:%.*]] = select i1 [[COND:%.*]], float [[C]], float [[A]] 8; CHECK-NEXT: ret float [[D]] 9; 10 %C = fadd float %A, %B 11 %D = select i1 %cond, float %C, float %A 12 ret float %D 13} 14 15define float @select_fpclass_fadd(i1 %cond, float nofpclass(nan) %A, float %B) { 16; CHECK-LABEL: @select_fpclass_fadd( 17; CHECK-NEXT: [[C:%.*]] = select i1 [[COND:%.*]], float [[B:%.*]], float -0.000000e+00 18; CHECK-NEXT: [[D:%.*]] = fadd float [[A:%.*]], [[C]] 19; CHECK-NEXT: ret float [[D]] 20; 21 %C = fadd float %A, %B 22 %D = select i1 %cond, float %C, float %A 23 ret float %D 24} 25 26define float @select_nnan_fadd(i1 %cond, float %A, float %B) { 27; CHECK-LABEL: @select_nnan_fadd( 28; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float -0.000000e+00 29; CHECK-NEXT: [[D:%.*]] = fadd float [[A:%.*]], [[C]] 30; CHECK-NEXT: ret float [[D]] 31; 32 %C = fadd float %A, %B 33 %D = select nnan i1 %cond, float %C, float %A 34 ret float %D 35} 36 37define float @select_nnan_fadd_swapped(i1 %cond, float %A, float %B) { 38; CHECK-LABEL: @select_nnan_fadd_swapped( 39; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float -0.000000e+00, float [[B:%.*]] 40; CHECK-NEXT: [[D:%.*]] = fadd float [[A:%.*]], [[C]] 41; CHECK-NEXT: ret float [[D]] 42; 43 %C = fadd float %A, %B 44 %D = select nnan i1 %cond, float %A, float %C 45 ret float %D 46} 47 48define float @select_nnan_fadd_fast_math(i1 %cond, float %A, float %B) { 49; CHECK-LABEL: @select_nnan_fadd_fast_math( 50; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float -0.000000e+00 51; CHECK-NEXT: [[D:%.*]] = fadd reassoc nnan arcp contract afn float [[A:%.*]], [[C]] 52; CHECK-NEXT: ret float [[D]] 53; 54 %C = fadd fast float %A, %B 55 %D = select nnan i1 %cond, float %C, float %A 56 ret float %D 57} 58 59define float @select_nnan_fadd_swapped_fast_math(i1 %cond, float %A, float %B) { 60; CHECK-LABEL: @select_nnan_fadd_swapped_fast_math( 61; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float -0.000000e+00, float [[B:%.*]] 62; CHECK-NEXT: [[D:%.*]] = fadd reassoc nnan arcp contract afn float [[A:%.*]], [[C]] 63; CHECK-NEXT: ret float [[D]] 64; 65 %C = fadd fast float %A, %B 66 %D = select nnan i1 %cond, float %A, float %C 67 ret float %D 68} 69 70define <4 x float> @select_nnan_nsz_fadd_v4f32(<4 x i1> %cond, <4 x float> %A, <4 x float> %B) { 71; CHECK-LABEL: @select_nnan_nsz_fadd_v4f32( 72; CHECK-NEXT: [[C:%.*]] = select nnan nsz <4 x i1> [[COND:%.*]], <4 x float> [[B:%.*]], <4 x float> zeroinitializer 73; CHECK-NEXT: [[D:%.*]] = fadd nnan nsz <4 x float> [[A:%.*]], [[C]] 74; CHECK-NEXT: ret <4 x float> [[D]] 75; 76 %C = fadd nsz nnan <4 x float> %A, %B 77 %D = select nsz nnan <4 x i1> %cond, <4 x float> %C, <4 x float> %A 78 ret <4 x float> %D 79} 80 81define <vscale x 4 x float> @select_nnan_nsz_fadd_nxv4f32(<vscale x 4 x i1> %cond, <vscale x 4 x float> %A, <vscale x 4 x float> %B) { 82; CHECK-LABEL: @select_nnan_nsz_fadd_nxv4f32( 83; CHECK-NEXT: [[C:%.*]] = select nnan nsz <vscale x 4 x i1> [[COND:%.*]], <vscale x 4 x float> [[B:%.*]], <vscale x 4 x float> zeroinitializer 84; CHECK-NEXT: [[D:%.*]] = fadd nnan nsz <vscale x 4 x float> [[A:%.*]], [[C]] 85; CHECK-NEXT: ret <vscale x 4 x float> [[D]] 86; 87 %C = fadd nnan nsz <vscale x 4 x float> %A, %B 88 %D = select nnan nsz <vscale x 4 x i1> %cond, <vscale x 4 x float> %C, <vscale x 4 x float> %A 89 ret <vscale x 4 x float> %D 90} 91 92define <vscale x 4 x float> @select_nnan_nsz_fadd_nxv4f32_swapops(<vscale x 4 x i1> %cond, <vscale x 4 x float> %A, <vscale x 4 x float> %B) { 93; CHECK-LABEL: @select_nnan_nsz_fadd_nxv4f32_swapops( 94; CHECK-NEXT: [[C:%.*]] = select fast <vscale x 4 x i1> [[COND:%.*]], <vscale x 4 x float> zeroinitializer, <vscale x 4 x float> [[B:%.*]] 95; CHECK-NEXT: [[D:%.*]] = fadd fast <vscale x 4 x float> [[A:%.*]], [[C]] 96; CHECK-NEXT: ret <vscale x 4 x float> [[D]] 97; 98 %C = fadd fast <vscale x 4 x float> %A, %B 99 %D = select nnan fast <vscale x 4 x i1> %cond, <vscale x 4 x float> %A, <vscale x 4 x float> %C 100 ret <vscale x 4 x float> %D 101} 102 103define float @select_nnan_fmul(i1 %cond, float %A, float %B) { 104; CHECK-LABEL: @select_nnan_fmul( 105; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float 1.000000e+00 106; CHECK-NEXT: [[D:%.*]] = fmul float [[A:%.*]], [[C]] 107; CHECK-NEXT: ret float [[D]] 108; 109 %C = fmul float %A, %B 110 %D = select nnan i1 %cond, float %C, float %A 111 ret float %D 112} 113 114define float @select_nnan_fmul_swapped(i1 %cond, float %A, float %B) { 115; CHECK-LABEL: @select_nnan_fmul_swapped( 116; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float 1.000000e+00, float [[B:%.*]] 117; CHECK-NEXT: [[D:%.*]] = fmul float [[A:%.*]], [[C]] 118; CHECK-NEXT: ret float [[D]] 119; 120 %C = fmul float %A, %B 121 %D = select nnan i1 %cond, float %A, float %C 122 ret float %D 123} 124 125define float @select_nnan_fmul_fast_math(i1 %cond, float %A, float %B) { 126; CHECK-LABEL: @select_nnan_fmul_fast_math( 127; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float 1.000000e+00 128; CHECK-NEXT: [[D:%.*]] = fmul reassoc nnan arcp contract afn float [[A:%.*]], [[C]] 129; CHECK-NEXT: ret float [[D]] 130; 131 %C = fmul fast float %A, %B 132 %D = select nnan i1 %cond, float %C, float %A 133 ret float %D 134} 135 136define float @select_nnan_fmul_swapped_fast_math(i1 %cond, float %A, float %B) { 137; CHECK-LABEL: @select_nnan_fmul_swapped_fast_math( 138; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float 1.000000e+00, float [[B:%.*]] 139; CHECK-NEXT: [[D:%.*]] = fmul reassoc nnan arcp contract afn float [[A:%.*]], [[C]] 140; CHECK-NEXT: ret float [[D]] 141; 142 %C = fmul fast float %A, %B 143 %D = select nnan i1 %cond, float %A, float %C 144 ret float %D 145} 146 147define float @select_nnan_fsub(i1 %cond, float %A, float %B) { 148; CHECK-LABEL: @select_nnan_fsub( 149; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float 0.000000e+00 150; CHECK-NEXT: [[D:%.*]] = fsub float [[A:%.*]], [[C]] 151; CHECK-NEXT: ret float [[D]] 152; 153 %C = fsub float %A, %B 154 %D = select nnan i1 %cond, float %C, float %A 155 ret float %D 156} 157 158define float @select_nnan_fsub_swapped(i1 %cond, float %A, float %B) { 159; CHECK-LABEL: @select_nnan_fsub_swapped( 160; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float 0.000000e+00, float [[B:%.*]] 161; CHECK-NEXT: [[D:%.*]] = fsub float [[A:%.*]], [[C]] 162; CHECK-NEXT: ret float [[D]] 163; 164 %C = fsub float %A, %B 165 %D = select nnan i1 %cond, float %A, float %C 166 ret float %D 167} 168 169define float @select_nnan_fsub_fast_math(i1 %cond, float %A, float %B) { 170; CHECK-LABEL: @select_nnan_fsub_fast_math( 171; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float 0.000000e+00 172; CHECK-NEXT: [[D:%.*]] = fsub reassoc nnan arcp contract afn float [[A:%.*]], [[C]] 173; CHECK-NEXT: ret float [[D]] 174; 175 %C = fsub fast float %A, %B 176 %D = select nnan i1 %cond, float %C, float %A 177 ret float %D 178} 179 180define float @select_nnan_fsub_swapped_fast_math(i1 %cond, float %A, float %B) { 181; CHECK-LABEL: @select_nnan_fsub_swapped_fast_math( 182; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float 0.000000e+00, float [[B:%.*]] 183; CHECK-NEXT: [[D:%.*]] = fsub reassoc nnan arcp contract afn float [[A:%.*]], [[C]] 184; CHECK-NEXT: ret float [[D]] 185; 186 %C = fsub fast float %A, %B 187 %D = select nnan i1 %cond, float %A, float %C 188 ret float %D 189} 190 191define <4 x float> @select_nnan_nsz_fsub_v4f32(<4 x i1> %cond, <4 x float> %A, <4 x float> %B) { 192; CHECK-LABEL: @select_nnan_nsz_fsub_v4f32( 193; CHECK-NEXT: [[C:%.*]] = select nnan nsz <4 x i1> [[COND:%.*]], <4 x float> [[B:%.*]], <4 x float> zeroinitializer 194; CHECK-NEXT: [[D:%.*]] = fsub <4 x float> [[A:%.*]], [[C]] 195; CHECK-NEXT: ret <4 x float> [[D]] 196; 197 %C = fsub <4 x float> %A, %B 198 %D = select nnan nsz <4 x i1> %cond, <4 x float> %C, <4 x float> %A 199 ret <4 x float> %D 200} 201 202define <vscale x 4 x float> @select_nnan_nsz_fsub_nxv4f32(<vscale x 4 x i1> %cond, <vscale x 4 x float> %A, <vscale x 4 x float> %B) { 203; CHECK-LABEL: @select_nnan_nsz_fsub_nxv4f32( 204; CHECK-NEXT: [[C:%.*]] = select nnan nsz <vscale x 4 x i1> [[COND:%.*]], <vscale x 4 x float> [[B:%.*]], <vscale x 4 x float> zeroinitializer 205; CHECK-NEXT: [[D:%.*]] = fsub <vscale x 4 x float> [[A:%.*]], [[C]] 206; CHECK-NEXT: ret <vscale x 4 x float> [[D]] 207; 208 %C = fsub <vscale x 4 x float> %A, %B 209 %D = select nnan nsz <vscale x 4 x i1> %cond, <vscale x 4 x float> %C, <vscale x 4 x float> %A 210 ret <vscale x 4 x float> %D 211} 212 213; 'fsub' can only fold on the amount subtracted. 214define float @select_nnan_fsub_invalid(i1 %cond, float %A, float %B) { 215; CHECK-LABEL: @select_nnan_fsub_invalid( 216; CHECK-NEXT: [[C:%.*]] = fsub float [[B:%.*]], [[A:%.*]] 217; CHECK-NEXT: [[D:%.*]] = select nnan i1 [[COND:%.*]], float [[C]], float [[A]] 218; CHECK-NEXT: ret float [[D]] 219; 220 %C = fsub float %B, %A 221 %D = select nnan i1 %cond, float %C, float %A 222 ret float %D 223} 224 225define float @select_nnan_fdiv(i1 %cond, float %A, float %B) { 226; CHECK-LABEL: @select_nnan_fdiv( 227; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float 1.000000e+00 228; CHECK-NEXT: [[D:%.*]] = fdiv float [[A:%.*]], [[C]] 229; CHECK-NEXT: ret float [[D]] 230; 231 %C = fdiv float %A, %B 232 %D = select nnan i1 %cond, float %C, float %A 233 ret float %D 234} 235 236define float @select_nnan_fdiv_swapped(i1 %cond, float %A, float %B) { 237; CHECK-LABEL: @select_nnan_fdiv_swapped( 238; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float 1.000000e+00, float [[B:%.*]] 239; CHECK-NEXT: [[D:%.*]] = fdiv float [[A:%.*]], [[C]] 240; CHECK-NEXT: ret float [[D]] 241; 242 %C = fdiv float %A, %B 243 %D = select nnan i1 %cond, float %A, float %C 244 ret float %D 245} 246 247define float @select_nnan_fdiv_fast_math(i1 %cond, float %A, float %B) { 248; CHECK-LABEL: @select_nnan_fdiv_fast_math( 249; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float [[B:%.*]], float 1.000000e+00 250; CHECK-NEXT: [[D:%.*]] = fdiv reassoc nnan arcp contract afn float [[A:%.*]], [[C]] 251; CHECK-NEXT: ret float [[D]] 252; 253 %C = fdiv fast float %A, %B 254 %D = select nnan i1 %cond, float %C, float %A 255 ret float %D 256} 257 258define float @select_nnan_fdiv_swapped_fast_math(i1 %cond, float %A, float %B) { 259; CHECK-LABEL: @select_nnan_fdiv_swapped_fast_math( 260; CHECK-NEXT: [[C:%.*]] = select nnan i1 [[COND:%.*]], float 1.000000e+00, float [[B:%.*]] 261; CHECK-NEXT: [[D:%.*]] = fdiv reassoc nnan arcp contract afn float [[A:%.*]], [[C]] 262; CHECK-NEXT: ret float [[D]] 263; 264 %C = fdiv fast float %A, %B 265 %D = select nnan i1 %cond, float %A, float %C 266 ret float %D 267} 268 269; 'fdiv' can only fold on the divisor amount. 270define float @select_nnan_fdiv_invalid(i1 %cond, float %A, float %B) { 271; CHECK-LABEL: @select_nnan_fdiv_invalid( 272; CHECK-NEXT: [[C:%.*]] = fdiv float [[B:%.*]], [[A:%.*]] 273; CHECK-NEXT: [[D:%.*]] = select nnan i1 [[COND:%.*]], float [[C]], float [[A]] 274; CHECK-NEXT: ret float [[D]] 275; 276 %C = fdiv float %B, %A 277 %D = select nnan i1 %cond, float %C, float %A 278 ret float %D 279} 280