Skip to content
This repository was archived by the owner on Sep 15, 2025. It is now read-only.

Commit b77230b

Browse files
committed
Revert "Revert "ConstantFolding: Constant fold denormal inputs to canonicalize for IEEE""
This reverts commit 2a38970. The CTS failures have been fixed by an LLPC patch that sets denormal-fp-math attributes earlier. Change-Id: I8744b15750a96393fd266c7d9cf0e84838d62365
1 parent fdb5f9b commit b77230b

File tree

2 files changed

+244
-12
lines changed

2 files changed

+244
-12
lines changed

llvm/lib/Analysis/ConstantFolding.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1955,9 +1955,8 @@ static Constant *constantFoldCanonicalize(const Type *Ty, const CallBase *CI,
19551955
DenormalMode DenormMode =
19561956
CI->getFunction()->getDenormalMode(Src.getSemantics());
19571957

1958-
// TODO: Should allow folding for pure IEEE.
19591958
if (DenormMode == DenormalMode::getIEEE())
1960-
return nullptr;
1959+
return ConstantFP::get(CI->getContext(), Src);
19611960

19621961
if (DenormMode.Input == DenormalMode::Dynamic)
19631962
return nullptr;

llvm/test/Transforms/InstSimplify/canonicalize.ll

Lines changed: 243 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ define <2 x float> @canonicalize_poison_vector() {
7575

7676
define float @canonicalize_denorm() {
7777
; CHECK-LABEL: @canonicalize_denorm(
78-
; CHECK-NEXT: [[RET:%.*]] = call float @llvm.canonicalize.f32(float 0x380FFFFFC0000000)
79-
; CHECK-NEXT: ret float [[RET]]
78+
; CHECK-NEXT: ret float 0x380FFFFFC0000000
8079
;
8180
%ret = call float @llvm.canonicalize.f32(float bitcast (i32 8388607 to float))
8281
ret float %ret
@@ -370,8 +369,7 @@ define double @canonicalize_1.0_f64() {
370369

371370
define double @canonicalize_0x00000000000001_f64() {
372371
; CHECK-LABEL: @canonicalize_0x00000000000001_f64(
373-
; CHECK-NEXT: [[RET:%.*]] = call double @llvm.canonicalize.f64(double 4.940660e-324)
374-
; CHECK-NEXT: ret double [[RET]]
372+
; CHECK-NEXT: ret double 4.940660e-324
375373
;
376374
%ret = call double @llvm.canonicalize.f64(double 0x00000000000001)
377375
ret double %ret
@@ -415,8 +413,7 @@ define half @canonicalize_1.0_f16() {
415413

416414
define half @canonicalize_0x0001_f16() {
417415
; CHECK-LABEL: @canonicalize_0x0001_f16(
418-
; CHECK-NEXT: [[RET:%.*]] = call half @llvm.canonicalize.f16(half 0xH0001)
419-
; CHECK-NEXT: ret half [[RET]]
416+
; CHECK-NEXT: ret half 0xH0001
420417
;
421418
%ret = call half @llvm.canonicalize.f16(half 0xH0001)
422419
ret half %ret
@@ -460,8 +457,7 @@ define fp128 @canonicalize_1.0_fp128() {
460457

461458
define fp128 @canonicalize_0x00000000000000000000000000000001_fp128() {
462459
; CHECK-LABEL: @canonicalize_0x00000000000000000000000000000001_fp128(
463-
; CHECK-NEXT: [[RET:%.*]] = call fp128 @llvm.canonicalize.f128(fp128 0xL00000000000000000000000000000001)
464-
; CHECK-NEXT: ret fp128 [[RET]]
460+
; CHECK-NEXT: ret fp128 0xL00000000000000000000000000000001
465461
;
466462
%ret = call fp128 @llvm.canonicalize.fp128(fp128 0xL00000000000000000000000000000001)
467463
ret fp128 %ret
@@ -514,8 +510,7 @@ define bfloat @canonicalize_1.0_bf16() {
514510

515511
define bfloat @canonicalize_0x0001_bf16() {
516512
; CHECK-LABEL: @canonicalize_0x0001_bf16(
517-
; CHECK-NEXT: [[RET:%.*]] = call bfloat @llvm.canonicalize.bf16(bfloat 0xR0001)
518-
; CHECK-NEXT: ret bfloat [[RET]]
513+
; CHECK-NEXT: ret bfloat 0xR0001
519514
;
520515
%ret = call bfloat @llvm.canonicalize.bf16(bfloat 0xR0001)
521516
ret bfloat %ret
@@ -767,6 +762,243 @@ define ppc_fp128 @canonicalize_neg1.0_ppcf128() {
767762
ret ppc_fp128 %ret
768763
}
769764

765+
; --------------------------------------------------------------------
766+
; Test folds of using canonicalize + is.fpclass to inspect the denormal mode.
767+
; --------------------------------------------------------------------
768+
769+
define i1 @is_poszero_daz_enabled_check_dynamic() "denormal-fp-math"="ieee,dynamic" {
770+
; CHECK-LABEL: @is_poszero_daz_enabled_check_dynamic(
771+
; CHECK-NEXT: [[CANONICAL:%.*]] = call float @llvm.canonicalize.f32(float 0x36A0000000000000)
772+
; CHECK-NEXT: [[IS_POS_ZERO:%.*]] = call i1 @llvm.is.fpclass.f32(float [[CANONICAL]], i32 64)
773+
; CHECK-NEXT: ret i1 [[IS_POS_ZERO]]
774+
;
775+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
776+
%is.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 64)
777+
ret i1 %is.pos.zero
778+
}
779+
780+
define i1 @is_preserve_sign_daz_enabled_check_dynamic() "denormal-fp-math"="ieee,dynamic" {
781+
; CHECK-LABEL: @is_preserve_sign_daz_enabled_check_dynamic(
782+
; CHECK-NEXT: [[CANONICAL:%.*]] = call float @llvm.canonicalize.f32(float 0xB6A0000000000000)
783+
; CHECK-NEXT: [[IS_NEG_ZERO:%.*]] = call i1 @llvm.is.fpclass.f32(float [[CANONICAL]], i32 32)
784+
; CHECK-NEXT: ret i1 [[IS_NEG_ZERO]]
785+
;
786+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
787+
%is.neg.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 32)
788+
ret i1 %is.neg.zero
789+
}
790+
791+
define i1 @is_positive_zero_daz_enabled_check_dynamic() "denormal-fp-math"="ieee,dynamic" {
792+
; CHECK-LABEL: @is_positive_zero_daz_enabled_check_dynamic(
793+
; CHECK-NEXT: [[CANONICAL:%.*]] = call float @llvm.canonicalize.f32(float 0xB6A0000000000000)
794+
; CHECK-NEXT: [[IS_POS_ZERO:%.*]] = call i1 @llvm.is.fpclass.f32(float [[CANONICAL]], i32 64)
795+
; CHECK-NEXT: ret i1 [[IS_POS_ZERO]]
796+
;
797+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
798+
%is.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 64)
799+
ret i1 %is.pos.zero
800+
}
801+
802+
define i1 @is_any_daz_enabled_check_dynamic() "denormal-fp-math"="ieee,dynamic" {
803+
; CHECK-LABEL: @is_any_daz_enabled_check_dynamic(
804+
; CHECK-NEXT: [[CANONICAL:%.*]] = call float @llvm.canonicalize.f32(float 0xB6A0000000000000)
805+
; CHECK-NEXT: [[IS_ANY_ZERO:%.*]] = call i1 @llvm.is.fpclass.f32(float [[CANONICAL]], i32 96)
806+
; CHECK-NEXT: ret i1 [[IS_ANY_ZERO]]
807+
;
808+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
809+
%is.any.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 96)
810+
ret i1 %is.any.zero
811+
}
812+
813+
define i1 @is_not_daz_enabled_check_dynamic() "denormal-fp-math"="ieee,dynamic" {
814+
; CHECK-LABEL: @is_not_daz_enabled_check_dynamic(
815+
; CHECK-NEXT: [[CANONICAL:%.*]] = call float @llvm.canonicalize.f32(float 0x36A0000000000000)
816+
; CHECK-NEXT: [[IS_NOT_POS_ZERO:%.*]] = call i1 @llvm.is.fpclass.f32(float [[CANONICAL]], i32 959)
817+
; CHECK-NEXT: ret i1 [[IS_NOT_POS_ZERO]]
818+
;
819+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
820+
%is.not.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 959)
821+
ret i1 %is.not.pos.zero
822+
}
823+
824+
define i1 @is_poszero_daz_enabled_check_ieee() "denormal-fp-math"="ieee,ieee" {
825+
; CHECK-LABEL: @is_poszero_daz_enabled_check_ieee(
826+
; CHECK-NEXT: ret i1 false
827+
;
828+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
829+
%is.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 64)
830+
ret i1 %is.pos.zero
831+
}
832+
833+
define i1 @is_preserve_sign_daz_enabled_check_ieee() "denormal-fp-math"="ieee,ieee" {
834+
; CHECK-LABEL: @is_preserve_sign_daz_enabled_check_ieee(
835+
; CHECK-NEXT: ret i1 false
836+
;
837+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
838+
%is.neg.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 32)
839+
ret i1 %is.neg.zero
840+
}
841+
842+
define i1 @is_positive_zero_daz_enabled_check_ieee() "denormal-fp-math"="ieee,ieee" {
843+
; CHECK-LABEL: @is_positive_zero_daz_enabled_check_ieee(
844+
; CHECK-NEXT: ret i1 false
845+
;
846+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
847+
%is.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 64)
848+
ret i1 %is.pos.zero
849+
}
850+
851+
define i1 @is_any_daz_enabled_check_ieee() "denormal-fp-math"="ieee,ieee" {
852+
; CHECK-LABEL: @is_any_daz_enabled_check_ieee(
853+
; CHECK-NEXT: ret i1 false
854+
;
855+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
856+
%is.any.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 96)
857+
ret i1 %is.any.zero
858+
}
859+
860+
define i1 @is_not_daz_enabled_check_ieee() "denormal-fp-math"="ieee,ieee" {
861+
; CHECK-LABEL: @is_not_daz_enabled_check_ieee(
862+
; CHECK-NEXT: ret i1 true
863+
;
864+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
865+
%is.not.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 959)
866+
ret i1 %is.not.pos.zero
867+
}
868+
869+
define i1 @is_poszero_daz_enabled_check_preserve_sign() "denormal-fp-math"="ieee,preserve-sign" {
870+
; CHECK-LABEL: @is_poszero_daz_enabled_check_preserve_sign(
871+
; CHECK-NEXT: ret i1 true
872+
;
873+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
874+
%is.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 64)
875+
ret i1 %is.pos.zero
876+
}
877+
878+
define i1 @is_preserve_sign_daz_enabled_check_preserve_sign() "denormal-fp-math"="ieee,preserve-sign" {
879+
; CHECK-LABEL: @is_preserve_sign_daz_enabled_check_preserve_sign(
880+
; CHECK-NEXT: ret i1 true
881+
;
882+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
883+
%is.neg.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 32)
884+
ret i1 %is.neg.zero
885+
}
886+
887+
define i1 @is_positive_zero_daz_enabled_check_preserve_sign() "denormal-fp-math"="ieee,preserve-sign" {
888+
; CHECK-LABEL: @is_positive_zero_daz_enabled_check_preserve_sign(
889+
; CHECK-NEXT: ret i1 false
890+
;
891+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
892+
%is.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 64)
893+
ret i1 %is.pos.zero
894+
}
895+
896+
define i1 @is_any_daz_enabled_check_preserve_sign() "denormal-fp-math"="ieee,preserve-sign" {
897+
; CHECK-LABEL: @is_any_daz_enabled_check_preserve_sign(
898+
; CHECK-NEXT: ret i1 true
899+
;
900+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
901+
%is.any.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 96)
902+
ret i1 %is.any.zero
903+
}
904+
905+
define i1 @is_not_daz_enabled_check_preserve_sign() "denormal-fp-math"="ieee,preserve-sign" {
906+
; CHECK-LABEL: @is_not_daz_enabled_check_preserve_sign(
907+
; CHECK-NEXT: ret i1 false
908+
;
909+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
910+
%is.not.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 959)
911+
ret i1 %is.not.pos.zero
912+
}
913+
914+
define i1 @is_poszero_daz_enabled_check_positive_zero() "denormal-fp-math"="ieee,positive-zero" {
915+
; CHECK-LABEL: @is_poszero_daz_enabled_check_positive_zero(
916+
; CHECK-NEXT: ret i1 true
917+
;
918+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
919+
%is.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 64)
920+
ret i1 %is.pos.zero
921+
}
922+
923+
define i1 @is_preserve_sign_daz_enabled_check_positive_zero() "denormal-fp-math"="ieee,positive-zero" {
924+
; CHECK-LABEL: @is_preserve_sign_daz_enabled_check_positive_zero(
925+
; CHECK-NEXT: ret i1 false
926+
;
927+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
928+
%is.neg.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 32)
929+
ret i1 %is.neg.zero
930+
}
931+
932+
define i1 @is_positive_zero_daz_enabled_check_positive_zero() "denormal-fp-math"="ieee,positive-zero" {
933+
; CHECK-LABEL: @is_positive_zero_daz_enabled_check_positive_zero(
934+
; CHECK-NEXT: ret i1 true
935+
;
936+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
937+
%is.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 64)
938+
ret i1 %is.pos.zero
939+
}
940+
941+
define i1 @is_any_daz_enabled_check_positive_zero() "denormal-fp-math"="ieee,positive-zero" {
942+
; CHECK-LABEL: @is_any_daz_enabled_check_positive_zero(
943+
; CHECK-NEXT: ret i1 true
944+
;
945+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 -2147483647 to float))
946+
%is.any.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 96)
947+
ret i1 %is.any.zero
948+
}
949+
950+
define i1 @is_not_daz_enabled_check_positive_zero() "denormal-fp-math"="ieee,positive-zero" {
951+
; CHECK-LABEL: @is_not_daz_enabled_check_positive_zero(
952+
; CHECK-NEXT: ret i1 false
953+
;
954+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
955+
%is.not.pos.zero = call i1 @llvm.is.fpclass.f32(float %canonical, i32 959)
956+
ret i1 %is.not.pos.zero
957+
}
958+
959+
define i1 @is_poszero_daz_enabled_check_dynamic_bitcast() "denormal-fp-math"="ieee,dynamic" {
960+
; CHECK-LABEL: @is_poszero_daz_enabled_check_dynamic_bitcast(
961+
; CHECK-NEXT: [[CANONICAL:%.*]] = call float @llvm.canonicalize.f32(float 0x36A0000000000000)
962+
; CHECK-NEXT: [[BITCAST:%.*]] = bitcast float [[CANONICAL]] to i32
963+
; CHECK-NEXT: [[IS_POS_ZERO:%.*]] = icmp eq i32 [[BITCAST]], 0
964+
; CHECK-NEXT: ret i1 [[IS_POS_ZERO]]
965+
;
966+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
967+
%bitcast = bitcast float %canonical to i32
968+
%is.pos.zero = icmp eq i32 %bitcast, 0
969+
ret i1 %is.pos.zero
970+
}
971+
972+
define i1 @is_poszero_daz_enabled_check_preserve_sign_bitcast() "denormal-fp-math"="ieee,preserve-sign" {
973+
; CHECK-LABEL: @is_poszero_daz_enabled_check_preserve_sign_bitcast(
974+
; CHECK-NEXT: ret i1 true
975+
;
976+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
977+
%bitcast = bitcast float %canonical to i32
978+
%is.pos.zero = icmp eq i32 %bitcast, 0
979+
ret i1 %is.pos.zero
980+
}
981+
982+
define i1 @is_poszero_daz_enabled_check_positive_zero_bitcast() "denormal-fp-math"="ieee,positive-zero" {
983+
; CHECK-LABEL: @is_poszero_daz_enabled_check_positive_zero_bitcast(
984+
; CHECK-NEXT: ret i1 true
985+
;
986+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
987+
%bitcast = bitcast float %canonical to i32
988+
%is.pos.zero = icmp eq i32 %bitcast, 0
989+
ret i1 %is.pos.zero
990+
}
991+
992+
define i1 @is_poszero_daz_enabled_check_ieee_bitcast() "denormal-fp-math"="ieee,ieee" {
993+
; CHECK-LABEL: @is_poszero_daz_enabled_check_ieee_bitcast(
994+
; CHECK-NEXT: ret i1 false
995+
;
996+
%canonical = call float @llvm.canonicalize.f32(float bitcast (i32 1 to float))
997+
%bitcast = bitcast float %canonical to i32
998+
%is.pos.zero = icmp eq i32 %bitcast, 0
999+
ret i1 %is.pos.zero
1000+
}
1001+
7701002
declare bfloat @llvm.canonicalize.bf16(bfloat)
7711003
declare half @llvm.canonicalize.f16(half)
7721004
declare float @llvm.canonicalize.f32(float)
@@ -775,3 +1007,4 @@ declare double @llvm.canonicalize.f64(double)
7751007
declare fp128 @llvm.canonicalize.fp128(fp128)
7761008
declare x86_fp80 @llvm.canonicalize.f80(x86_fp80)
7771009
declare ppc_fp128 @llvm.canonicalize.ppcf128(ppc_fp128)
1010+
declare i1 @llvm.is.fpclass.f32(float, i32 immarg)

0 commit comments

Comments
 (0)