1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -S -instcombine | FileCheck %s 3 4; This file used to contain more tests that folded to true/false, 5; but those are all tested identically in InstSimplify now. 6; If any remaining tests are made to return true/false, that 7; functionality/testing may be better housed in InstSimplify 8; rather than InstCombine. 9 10define i1 @fabs_sqrt_src_maybe_nan(double %arg0, double %arg1) { 11; CHECK-LABEL: @fabs_sqrt_src_maybe_nan( 12; CHECK-NEXT: [[FABS:%.*]] = call double @llvm.fabs.f64(double [[ARG0:%.*]]) 13; CHECK-NEXT: [[OP:%.*]] = call double @llvm.sqrt.f64(double [[FABS]]) 14; CHECK-NEXT: [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00 15; CHECK-NEXT: ret i1 [[TMP]] 16; 17 %fabs = call double @llvm.fabs.f64(double %arg0) 18 %op = call double @llvm.sqrt.f64(double %fabs) 19 %tmp = fcmp ord double %op, %op 20 ret i1 %tmp 21} 22 23define i1 @select_maybe_nan_lhs(i1 %cond, double %lhs, double %arg1) { 24; CHECK-LABEL: @select_maybe_nan_lhs( 25; CHECK-NEXT: [[RHS:%.*]] = fadd nnan double [[ARG1:%.*]], 1.000000e+00 26; CHECK-NEXT: [[OP:%.*]] = select i1 [[COND:%.*]], double [[LHS:%.*]], double [[RHS]] 27; CHECK-NEXT: [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00 28; CHECK-NEXT: ret i1 [[TMP]] 29; 30 %rhs = fadd nnan double %arg1, 1.0 31 %op = select i1 %cond, double %lhs, double %rhs 32 %tmp = fcmp ord double %op, %op 33 ret i1 %tmp 34} 35 36define i1 @select_maybe_nan_rhs(i1 %cond, double %arg0, double %rhs) { 37; CHECK-LABEL: @select_maybe_nan_rhs( 38; CHECK-NEXT: [[LHS:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00 39; CHECK-NEXT: [[OP:%.*]] = select i1 [[COND:%.*]], double [[LHS]], double [[RHS:%.*]] 40; CHECK-NEXT: [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00 41; CHECK-NEXT: ret i1 [[TMP]] 42; 43 %lhs = fadd nnan double %arg0, 1.0 44 %op = select i1 %cond, double %lhs, double %rhs 45 %tmp = fcmp ord double %op, %op 46 ret i1 %tmp 47} 48 49define i1 @nnan_fadd(double %arg0, double %arg1) { 50; CHECK-LABEL: @nnan_fadd( 51; CHECK-NEXT: [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00 52; CHECK-NEXT: [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00 53; CHECK-NEXT: [[OP:%.*]] = fadd double [[NNAN_ARG0]], [[NNAN_ARG1]] 54; CHECK-NEXT: [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00 55; CHECK-NEXT: ret i1 [[TMP]] 56; 57 %nnan.arg0 = fadd nnan double %arg0, 1.0 58 %nnan.arg1 = fadd nnan double %arg0, 2.0 59 %op = fadd double %nnan.arg0, %nnan.arg1 60 %tmp = fcmp ord double %op, %op 61 ret i1 %tmp 62} 63 64define i1 @nnan_fadd_maybe_nan_lhs(double %arg0, double %arg1) { 65; CHECK-LABEL: @nnan_fadd_maybe_nan_lhs( 66; CHECK-NEXT: [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG1:%.*]], 1.000000e+00 67; CHECK-NEXT: [[OP:%.*]] = fadd double [[NNAN_ARG1]], [[ARG0:%.*]] 68; CHECK-NEXT: [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00 69; CHECK-NEXT: ret i1 [[TMP]] 70; 71 %nnan.arg1 = fadd nnan double %arg1, 1.0 72 %op = fadd double %arg0, %nnan.arg1 73 %tmp = fcmp ord double %op, %op 74 ret i1 %tmp 75} 76 77define i1 @nnan_fadd_maybe_nan_rhs(double %arg0, double %arg1) { 78; CHECK-LABEL: @nnan_fadd_maybe_nan_rhs( 79; CHECK-NEXT: [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00 80; CHECK-NEXT: [[OP:%.*]] = fadd double [[NNAN_ARG0]], [[ARG1:%.*]] 81; CHECK-NEXT: [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00 82; CHECK-NEXT: ret i1 [[TMP]] 83; 84 %nnan.arg0 = fadd nnan double %arg0, 1.0 85 %op = fadd double %nnan.arg0, %arg1 86 %tmp = fcmp ord double %op, %op 87 ret i1 %tmp 88} 89 90define i1 @nnan_fmul(double %arg0, double %arg1) { 91; CHECK-LABEL: @nnan_fmul( 92; CHECK-NEXT: [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00 93; CHECK-NEXT: [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00 94; CHECK-NEXT: [[OP:%.*]] = fmul double [[NNAN_ARG0]], [[NNAN_ARG1]] 95; CHECK-NEXT: [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00 96; CHECK-NEXT: ret i1 [[TMP]] 97; 98 %nnan.arg0 = fadd nnan double %arg0, 1.0 99 %nnan.arg1 = fadd nnan double %arg0, 2.0 100 %op = fmul double %nnan.arg0, %nnan.arg1 101 %tmp = fcmp ord double %op, %op 102 ret i1 %tmp 103} 104 105define i1 @nnan_fsub(double %arg0, double %arg1) { 106; CHECK-LABEL: @nnan_fsub( 107; CHECK-NEXT: [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00 108; CHECK-NEXT: [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00 109; CHECK-NEXT: [[OP:%.*]] = fsub double [[NNAN_ARG0]], [[NNAN_ARG1]] 110; CHECK-NEXT: [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00 111; CHECK-NEXT: ret i1 [[TMP]] 112; 113 %nnan.arg0 = fadd nnan double %arg0, 1.0 114 %nnan.arg1 = fadd nnan double %arg0, 2.0 115 %op = fsub double %nnan.arg0, %nnan.arg1 116 %tmp = fcmp ord double %op, %op 117 ret i1 %tmp 118} 119 120declare double @func() 121 122define i1 @nnan_fneg() { 123; CHECK-LABEL: @nnan_fneg( 124; CHECK-NEXT: [[NNAN:%.*]] = call nnan double @func() 125; CHECK-NEXT: ret i1 true 126; 127 %nnan = call nnan double @func() 128 %op = fsub double -0.0, %nnan 129 %tmp = fcmp ord double %op, %op 130 ret i1 %tmp 131} 132 133define i1 @nnan_unary_fneg() { 134; CHECK-LABEL: @nnan_unary_fneg( 135; CHECK-NEXT: [[NNAN:%.*]] = call nnan double @func() 136; CHECK-NEXT: ret i1 true 137; 138 %nnan = call nnan double @func() 139 %op = fneg double %nnan 140 %tmp = fcmp ord double %op, %op 141 ret i1 %tmp 142} 143 144define i1 @fpext_maybe_nan(float %arg0) { 145; CHECK-LABEL: @fpext_maybe_nan( 146; CHECK-NEXT: [[TMP:%.*]] = fcmp ord float [[ARG0:%.*]], 0.000000e+00 147; CHECK-NEXT: ret i1 [[TMP]] 148; 149 %op = fpext float %arg0 to double 150 %tmp = fcmp ord double %op, %op 151 ret i1 %tmp 152} 153 154define i1 @fptrunc_maybe_nan(double %arg0) { 155; CHECK-LABEL: @fptrunc_maybe_nan( 156; CHECK-NEXT: [[OP:%.*]] = fptrunc double [[ARG0:%.*]] to float 157; CHECK-NEXT: [[TMP:%.*]] = fcmp ord float [[OP]], 0.000000e+00 158; CHECK-NEXT: ret i1 [[TMP]] 159; 160 %op = fptrunc double %arg0 to float 161 %tmp = fcmp ord float %op, %op 162 ret i1 %tmp 163} 164 165define i1 @nnan_fdiv(double %arg0, double %arg1) { 166; CHECK-LABEL: @nnan_fdiv( 167; CHECK-NEXT: [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00 168; CHECK-NEXT: [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00 169; CHECK-NEXT: [[OP:%.*]] = fdiv double [[NNAN_ARG0]], [[NNAN_ARG1]] 170; CHECK-NEXT: [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00 171; CHECK-NEXT: ret i1 [[TMP]] 172; 173 %nnan.arg0 = fadd nnan double %arg0, 1.0 174 %nnan.arg1 = fadd nnan double %arg0, 2.0 175 %op = fdiv double %nnan.arg0, %nnan.arg1 176 %tmp = fcmp ord double %op, %op 177 ret i1 %tmp 178} 179 180define i1 @nnan_frem(double %arg0, double %arg1) { 181; CHECK-LABEL: @nnan_frem( 182; CHECK-NEXT: [[NNAN_ARG0:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00 183; CHECK-NEXT: [[NNAN_ARG1:%.*]] = fadd nnan double [[ARG0]], 2.000000e+00 184; CHECK-NEXT: [[OP:%.*]] = frem double [[NNAN_ARG0]], [[NNAN_ARG1]] 185; CHECK-NEXT: [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00 186; CHECK-NEXT: ret i1 [[TMP]] 187; 188 %nnan.arg0 = fadd nnan double %arg0, 1.0 189 %nnan.arg1 = fadd nnan double %arg0, 2.0 190 %op = frem double %nnan.arg0, %nnan.arg1 191 %tmp = fcmp ord double %op, %op 192 ret i1 %tmp 193} 194 195declare double @llvm.sqrt.f64(double) 196declare double @llvm.fabs.f64(double) 197declare double @llvm.canonicalize.f64(double) 198declare double @llvm.copysign.f64(double, double) 199declare double @llvm.exp.f64(double) 200declare double @llvm.exp2.f64(double) 201declare double @llvm.floor.f64(double) 202declare double @llvm.ceil.f64(double) 203declare double @llvm.trunc.f64(double) 204declare double @llvm.rint.f64(double) 205declare double @llvm.nearbyint.f64(double) 206declare double @llvm.round.f64(double) 207 208