| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | |
| ; RUN: opt -S -passes=instcombine %s | FileCheck %s | |
| ; -------------------------------------------------------------------- | |
| ; (@canonicalize(x) == @canonicalize(y)) is equivalent to to (x == y) | |
| ; -------------------------------------------------------------------- | |
| define i1 @canonicalize_oeq_canonicalize_f32(float %x, float %y) { | |
| ; CHECK-LABEL: @canonicalize_oeq_canonicalize_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %canon.y = call float @llvm.canonicalize.f32(float %y) | |
| %cmp = fcmp oeq float %canon.x, %canon.y | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_oeq_canonicalize_f32_flags(float %x, float %y) { | |
| ; CHECK-LABEL: @canonicalize_oeq_canonicalize_f32_flags( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz oeq float [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %canon.y = call float @llvm.canonicalize.f32(float %y) | |
| %cmp = fcmp nsz oeq float %canon.x, %canon.y | |
| ret i1 %cmp | |
| } | |
| define <2 x i1> @canonicalize_oeq_canonicalize_v2f32(<2 x float> %x, <2 x float> %y) { | |
| ; CHECK-LABEL: @canonicalize_oeq_canonicalize_v2f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq <2 x float> [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret <2 x i1> [[CMP]] | |
| ; | |
| %canon.x = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> %x) | |
| %canon.y = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> %y) | |
| %cmp = fcmp oeq <2 x float> %canon.x, %canon.y | |
| ret <2 x i1> %cmp | |
| } | |
| define i1 @canonicalize_ueq_canonicalize_f32(float %x, float %y) { | |
| ; CHECK-LABEL: @canonicalize_ueq_canonicalize_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq float [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %canon.y = call float @llvm.canonicalize.f32(float %y) | |
| %cmp = fcmp ueq float %canon.x, %canon.y | |
| ret i1 %cmp | |
| } | |
| define <2 x i1> @canonicalize_ueq_canonicalize_v2f32(<2 x float> %x, <2 x float> %y) { | |
| ; CHECK-LABEL: @canonicalize_ueq_canonicalize_v2f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq <2 x float> [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret <2 x i1> [[CMP]] | |
| ; | |
| %canon.x = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> %x) | |
| %canon.y = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> %y) | |
| %cmp = fcmp ueq <2 x float> %canon.x, %canon.y | |
| ret <2 x i1> %cmp | |
| } | |
| define i1 @canonicalize_one_canonicalize_f32(float %x, float %y) { | |
| ; CHECK-LABEL: @canonicalize_one_canonicalize_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp one float [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %canon.y = call float @llvm.canonicalize.f32(float %y) | |
| %cmp = fcmp one float %canon.x, %canon.y | |
| ret i1 %cmp | |
| } | |
| define <2 x i1> @canonicalize_one_canonicalize_v2f32(<2 x float> %x, <2 x float> %y) { | |
| ; CHECK-LABEL: @canonicalize_one_canonicalize_v2f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp one <2 x float> [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret <2 x i1> [[CMP]] | |
| ; | |
| %canon.x = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> %x) | |
| %canon.y = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> %y) | |
| %cmp = fcmp one <2 x float> %canon.x, %canon.y | |
| ret <2 x i1> %cmp | |
| } | |
| define i1 @canonicalize_une_canonicalize_f32(float %x, float %y) { | |
| ; CHECK-LABEL: @canonicalize_une_canonicalize_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp une float [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %canon.y = call float @llvm.canonicalize.f32(float %y) | |
| %cmp = fcmp une float %canon.x, %canon.y | |
| ret i1 %cmp | |
| } | |
| define <2 x i1> @canonicalize_une_canonicalize_v2f32(<2 x float> %x, <2 x float> %y) { | |
| ; CHECK-LABEL: @canonicalize_une_canonicalize_v2f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp une <2 x float> [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret <2 x i1> [[CMP]] | |
| ; | |
| %canon.x = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> %x) | |
| %canon.y = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> %y) | |
| %cmp = fcmp une <2 x float> %canon.x, %canon.y | |
| ret <2 x i1> %cmp | |
| } | |
| define i1 @canonicalize_ogt_canonicalize_f32(float %x, float %y) { | |
| ; CHECK-LABEL: @canonicalize_ogt_canonicalize_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %canon.y = call float @llvm.canonicalize.f32(float %y) | |
| %cmp = fcmp ogt float %canon.x, %canon.y | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_oge_canonicalize_f32(float %x, float %y) { | |
| ; CHECK-LABEL: @canonicalize_oge_canonicalize_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp oge float [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %canon.y = call float @llvm.canonicalize.f32(float %y) | |
| %cmp = fcmp oge float %canon.x, %canon.y | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_olt_canonicalize_f32(float %x, float %y) { | |
| ; CHECK-LABEL: @canonicalize_olt_canonicalize_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %canon.y = call float @llvm.canonicalize.f32(float %y) | |
| %cmp = fcmp olt float %canon.x, %canon.y | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_ole_canonicalize_f32(float %x, float %y) { | |
| ; CHECK-LABEL: @canonicalize_ole_canonicalize_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp ole float [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %canon.y = call float @llvm.canonicalize.f32(float %y) | |
| %cmp = fcmp ole float %canon.x, %canon.y | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_ord_canonicalize_f32(float %x, float %y) { | |
| ; CHECK-LABEL: @canonicalize_ord_canonicalize_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %canon.y = call float @llvm.canonicalize.f32(float %y) | |
| %cmp = fcmp ord float %canon.x, %canon.y | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_ugt_canonicalize_f32(float %x, float %y) { | |
| ; CHECK-LABEL: @canonicalize_ugt_canonicalize_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt float [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %canon.y = call float @llvm.canonicalize.f32(float %y) | |
| %cmp = fcmp ugt float %canon.x, %canon.y | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_uge_canonicalize_f32(float %x, float %y) { | |
| ; CHECK-LABEL: @canonicalize_uge_canonicalize_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp uge float [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %canon.y = call float @llvm.canonicalize.f32(float %y) | |
| %cmp = fcmp uge float %canon.x, %canon.y | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_ult_canonicalize_f32(float %x, float %y) { | |
| ; CHECK-LABEL: @canonicalize_ult_canonicalize_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp ult float [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %canon.y = call float @llvm.canonicalize.f32(float %y) | |
| %cmp = fcmp ult float %canon.x, %canon.y | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_ule_canonicalize_f32(float %x, float %y) { | |
| ; CHECK-LABEL: @canonicalize_ule_canonicalize_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp ule float [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %canon.y = call float @llvm.canonicalize.f32(float %y) | |
| %cmp = fcmp ule float %canon.x, %canon.y | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_uno_canonicalize_f32(float %x, float %y) { | |
| ; CHECK-LABEL: @canonicalize_uno_canonicalize_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp uno float [[X:%.*]], [[Y:%.*]] | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %canon.y = call float @llvm.canonicalize.f32(float %y) | |
| %cmp = fcmp uno float %canon.x, %canon.y | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_oeq_y_f32() { | |
| ; CHECK-LABEL: @canonicalize_oeq_y_f32( | |
| ; CHECK-NEXT: [[X:%.*]] = call float @gen_f32() | |
| ; CHECK-NEXT: [[Y:%.*]] = call float @gen_f32() | |
| ; CHECK-NEXT: [[CANON_X:%.*]] = call float @llvm.canonicalize.f32(float [[X]]) | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[CANON_X]], [[Y]] | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %x = call float @gen_f32() | |
| %y = call float @gen_f32() | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %cmp = fcmp oeq float %canon.x, %y | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_oeq_y_commute_f32() { | |
| ; CHECK-LABEL: @canonicalize_oeq_y_commute_f32( | |
| ; CHECK-NEXT: [[X:%.*]] = call float @gen_f32() | |
| ; CHECK-NEXT: [[Y:%.*]] = call float @gen_f32() | |
| ; CHECK-NEXT: [[CANON_Y:%.*]] = call float @llvm.canonicalize.f32(float [[Y]]) | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[X]], [[CANON_Y]] | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %x = call float @gen_f32() | |
| %y = call float @gen_f32() | |
| %canon.y = call float @llvm.canonicalize.f32(float %y) | |
| %cmp = fcmp oeq float %x, %canon.y | |
| ret i1 %cmp | |
| } | |
| ; -------------------------------------------------------------------- | |
| ; (@canonicalize(x) == x) is equivalent to (x == x) | |
| ; -------------------------------------------------------------------- | |
| define i1 @canonicalize_oeq_arg_f32(float %x) { | |
| ; CHECK-LABEL: @canonicalize_oeq_arg_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00 | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %cmp = fcmp oeq float %canon.x, %x | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_oeq_arg_f32_flags(float %x) { | |
| ; CHECK-LABEL: @canonicalize_oeq_arg_f32_flags( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz ord float [[X:%.*]], 0.000000e+00 | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %cmp = fcmp nsz oeq float %canon.x, %x | |
| ret i1 %cmp | |
| } | |
| declare float @gen_f32() | |
| declare <2 x float> @gen_v2f32() | |
| define i1 @canonicalize_oeq_arg_f32_commute() { | |
| ; CHECK-LABEL: @canonicalize_oeq_arg_f32_commute( | |
| ; CHECK-NEXT: [[X:%.*]] = call float @gen_f32() | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz ord float [[X]], 0.000000e+00 | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %x = call float @gen_f32() ; thwart complexity-based canonicalization | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %cmp = fcmp nsz oeq float %x, %canon.x | |
| ret i1 %cmp | |
| } | |
| define <2 x i1> @canonicalize_oeq_arg_v2f32(<2 x float> %x) { | |
| ; CHECK-LABEL: @canonicalize_oeq_arg_v2f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp ord <2 x float> [[X:%.*]], zeroinitializer | |
| ; CHECK-NEXT: ret <2 x i1> [[CMP]] | |
| ; | |
| %canon.x = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> %x) | |
| %cmp = fcmp oeq <2 x float> %canon.x, %x | |
| ret <2 x i1> %cmp | |
| } | |
| define <2 x i1> @canonicalize_oeq_arg_v2f32_commute() { | |
| ; CHECK-LABEL: @canonicalize_oeq_arg_v2f32_commute( | |
| ; CHECK-NEXT: [[X:%.*]] = call <2 x float> @gen_v2f32() | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp ord <2 x float> [[X]], zeroinitializer | |
| ; CHECK-NEXT: ret <2 x i1> [[CMP]] | |
| ; | |
| %x = call <2 x float> @gen_v2f32() ; thwart complexity-based canonicalization | |
| %canon.x = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> %x) | |
| %cmp = fcmp oeq <2 x float> %x, %canon.x | |
| ret <2 x i1> %cmp | |
| } | |
| define i1 @canonicalize_ueq_arg_f32(float %x) { | |
| ; CHECK-LABEL: @canonicalize_ueq_arg_f32( | |
| ; CHECK-NEXT: ret i1 true | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %cmp = fcmp ueq float %canon.x, %x | |
| ret i1 %cmp | |
| } | |
| define <2 x i1> @canonicalize_ueq_arg_v2f32(<2 x float> %x) { | |
| ; CHECK-LABEL: @canonicalize_ueq_arg_v2f32( | |
| ; CHECK-NEXT: ret <2 x i1> splat (i1 true) | |
| ; | |
| %canon.x = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> %x) | |
| %cmp = fcmp ueq <2 x float> %canon.x, %x | |
| ret <2 x i1> %cmp | |
| } | |
| define i1 @canonicalize_one_arg_f32(float %x) { | |
| ; CHECK-LABEL: @canonicalize_one_arg_f32( | |
| ; CHECK-NEXT: ret i1 false | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %cmp = fcmp one float %canon.x, %x | |
| ret i1 %cmp | |
| } | |
| define <2 x i1> @canonicalize_one_arg_v2f32(<2 x float> %x) { | |
| ; CHECK-LABEL: @canonicalize_one_arg_v2f32( | |
| ; CHECK-NEXT: ret <2 x i1> zeroinitializer | |
| ; | |
| %canon.x = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> %x) | |
| %cmp = fcmp one <2 x float> %canon.x, %x | |
| ret <2 x i1> %cmp | |
| } | |
| define i1 @canonicalize_une_arg_f32(float %x) { | |
| ; CHECK-LABEL: @canonicalize_une_arg_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00 | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %cmp = fcmp une float %canon.x, %x | |
| ret i1 %cmp | |
| } | |
| define <2 x i1> @canonicalize_une_arg_v2f32(<2 x float> %x) { | |
| ; CHECK-LABEL: @canonicalize_une_arg_v2f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp uno <2 x float> [[X:%.*]], zeroinitializer | |
| ; CHECK-NEXT: ret <2 x i1> [[CMP]] | |
| ; | |
| %canon.x = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> %x) | |
| %cmp = fcmp une <2 x float> %canon.x, %x | |
| ret <2 x i1> %cmp | |
| } | |
| define i1 @canonicalize_ogt_arg_f32(float %x) { | |
| ; CHECK-LABEL: @canonicalize_ogt_arg_f32( | |
| ; CHECK-NEXT: ret i1 false | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %cmp = fcmp ogt float %canon.x, %x | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_oge_arg_f32(float %x) { | |
| ; CHECK-LABEL: @canonicalize_oge_arg_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00 | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %cmp = fcmp oge float %canon.x, %x | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_olt_arg_f32(float %x) { | |
| ; CHECK-LABEL: @canonicalize_olt_arg_f32( | |
| ; CHECK-NEXT: ret i1 false | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %cmp = fcmp olt float %canon.x, %x | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_ole_arg_f32(float %x) { | |
| ; CHECK-LABEL: @canonicalize_ole_arg_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00 | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %cmp = fcmp ole float %canon.x, %x | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_ord_arg_f32(float %x) { | |
| ; CHECK-LABEL: @canonicalize_ord_arg_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00 | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %cmp = fcmp ord float %canon.x, %x | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_ugt_arg_f32(float %x) { | |
| ; CHECK-LABEL: @canonicalize_ugt_arg_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00 | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %cmp = fcmp ugt float %canon.x, %x | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_uge_arg_f32(float %x) { | |
| ; CHECK-LABEL: @canonicalize_uge_arg_f32( | |
| ; CHECK-NEXT: ret i1 true | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %cmp = fcmp uge float %canon.x, %x | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_ult_arg_f32(float %x) { | |
| ; CHECK-LABEL: @canonicalize_ult_arg_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00 | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %cmp = fcmp ult float %canon.x, %x | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_ule_arg_f32(float %x) { | |
| ; CHECK-LABEL: @canonicalize_ule_arg_f32( | |
| ; CHECK-NEXT: ret i1 true | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %cmp = fcmp ule float %canon.x, %x | |
| ret i1 %cmp | |
| } | |
| define i1 @canonicalize_uno_arg_f32(float %x) { | |
| ; CHECK-LABEL: @canonicalize_uno_arg_f32( | |
| ; CHECK-NEXT: [[CMP:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00 | |
| ; CHECK-NEXT: ret i1 [[CMP]] | |
| ; | |
| %canon.x = call float @llvm.canonicalize.f32(float %x) | |
| %cmp = fcmp uno float %canon.x, %x | |
| ret i1 %cmp | |
| } | |
| ; -------------------------------------------------------------------- | |
| ; Others | |
| ; -------------------------------------------------------------------- | |
| ; Regression test checking that the vector version of llvm.canonicalize works. | |
| define <2 x i1> @vec_canonicalize_with_fpclass(<2 x float> %x) { | |
| ; CHECK-LABEL: @vec_canonicalize_with_fpclass( | |
| ; CHECK-NEXT: ret <2 x i1> zeroinitializer | |
| ; | |
| %canon = call <2 x float> @llvm.canonicalize.v2f32(<2 x float> %x) | |
| %fpclass = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %canon, i32 1) | |
| ret <2 x i1> %fpclass | |
| } | |
| declare float @llvm.canonicalize.f32(float) | |
| declare <2 x float> @llvm.canonicalize.v2f32(<2 x float>) | |
| declare <2 x i1> @llvm.is.fpclass.v2f32(<2 x float>, i32 immarg) |