; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 ; RUN: opt -passes=instcombine -mtriple=x86_64-unknown-unknown < %s -S | FileCheck %s ; Test relaxed negzero handling for X86 max/min intrinsics. declare <4 x float> @llvm.x86.sse.max.ps(<4 x float>, <4 x float>) declare <4 x float> @llvm.x86.sse.min.ps(<4 x float>, <4 x float>) declare <4 x float> @llvm.x86.sse.max.ss(<4 x float>, <4 x float>) declare <4 x float> @llvm.x86.sse.min.ss(<4 x float>, <4 x float>) ; For maxnum, allow -0.0 in the first operand only. define <4 x float> @test_max_allow_negzero_first() { ; CHECK-LABEL: define <4 x float> @test_max_allow_negzero_first() { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: ret <4 x float> splat (float 1.000000e+00) ; entry: %r = call <4 x float> @llvm.x86.sse.max.ps(<4 x float> , <4 x float> ) ret <4 x float> %r } ; For minnum, allow -0.0 in the second operand only. define <4 x float> @test_min_allow_negzero_second() { ; CHECK-LABEL: define <4 x float> @test_min_allow_negzero_second() { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: ret <4 x float> splat (float -0.000000e+00) ; entry: %r = call <4 x float> @llvm.x86.sse.min.ps(<4 x float> , <4 x float> ) ret <4 x float> %r } ; Negative test: max should not fold when -0.0 is in the second operand. define <4 x float> @test_max_disallow_negzero_second() { ; CHECK-LABEL: define <4 x float> @test_max_disallow_negzero_second() { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: [[R:%.*]] = call <4 x float> @llvm.x86.sse.max.ps(<4 x float> splat (float 1.000000e+00), <4 x float> splat (float -0.000000e+00)) ; CHECK-NEXT: ret <4 x float> [[R]] ; entry: %r = call <4 x float> @llvm.x86.sse.max.ps(<4 x float> , <4 x float> ) ret <4 x float> %r } ; Negative test: min should not fold when -0.0 is in the first operand. define <4 x float> @test_min_disallow_negzero_first() { ; CHECK-LABEL: define <4 x float> @test_min_disallow_negzero_first() { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: [[R:%.*]] = call <4 x float> @llvm.x86.sse.min.ps(<4 x float> splat (float -0.000000e+00), <4 x float> splat (float 1.000000e+00)) ; CHECK-NEXT: ret <4 x float> [[R]] ; entry: %r = call <4 x float> @llvm.x86.sse.min.ps(<4 x float> , <4 x float> ) ret <4 x float> %r } ; Scalar: only lane 0 is semantically constrained. define <4 x float> @test_max_ss_allow_negzero_first() { ; CHECK-LABEL: define <4 x float> @test_max_ss_allow_negzero_first() { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: ret <4 x float> ; entry: %r = call <4 x float> @llvm.x86.sse.max.ss(<4 x float> , <4 x float> ) ret <4 x float> %r } define <4 x float> @test_max_ss_disallow_negzero_second() { ; CHECK-LABEL: define <4 x float> @test_max_ss_disallow_negzero_second() { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: [[R:%.*]] = call <4 x float> @llvm.x86.sse.max.ss(<4 x float> , <4 x float> ) ; CHECK-NEXT: ret <4 x float> [[R]] ; entry: %r = call <4 x float> @llvm.x86.sse.max.ss(<4 x float> , <4 x float> ) ret <4 x float> %r } define <4 x float> @test_min_ss_allow_negzero_second() { ; CHECK-LABEL: define <4 x float> @test_min_ss_allow_negzero_second() { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: ret <4 x float> ; entry: %r = call <4 x float> @llvm.x86.sse.min.ss(<4 x float> , <4 x float> ) ret <4 x float> %r } define <4 x float> @test_min_ss_disallow_negzero_first() { ; CHECK-LABEL: define <4 x float> @test_min_ss_disallow_negzero_first() { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: [[R:%.*]] = call <4 x float> @llvm.x86.sse.min.ss(<4 x float> , <4 x float> ) ; CHECK-NEXT: ret <4 x float> [[R]] ; entry: %r = call <4 x float> @llvm.x86.sse.min.ss(<4 x float> , <4 x float> ) ret <4 x float> %r }