@@ -795,3 +795,333 @@ join:
795
795
store i8 %v , ptr %q , align 1
796
796
ret void
797
797
}
798
+
799
+ ; Dominating condition implies value already exists, optimize store
800
+ define void @remove_tautological_store_eq (ptr %x ) {
801
+ ; CHECK-LABEL: @remove_tautological_store_eq(
802
+ ; CHECK-NEXT: entry:
803
+ ; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[X:%.*]], align 4
804
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[VAL]], 4
805
+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_EQ:%.*]], label [[END:%.*]]
806
+ ; CHECK: if.eq:
807
+ ; CHECK-NEXT: br label [[END]]
808
+ ; CHECK: end:
809
+ ; CHECK-NEXT: ret void
810
+ ;
811
+ entry:
812
+ %val = load i32 , ptr %x , align 4
813
+ %cmp = icmp eq i32 %val , 4
814
+ br i1 %cmp , label %if.eq , label %end
815
+
816
+ if.eq:
817
+ store i32 4 , ptr %x , align 4
818
+ br label %end
819
+
820
+ end:
821
+ ret void
822
+ }
823
+
824
+ ; Dominating condition implies value already exists, optimize store
825
+ define void @remove_tautological_store_var (ptr %x , ptr %y ) {
826
+ ; CHECK-LABEL: @remove_tautological_store_var(
827
+ ; CHECK-NEXT: entry:
828
+ ; CHECK-NEXT: [[VALX:%.*]] = load i32, ptr [[X:%.*]], align 4
829
+ ; CHECK-NEXT: [[VALY:%.*]] = load i32, ptr [[Y:%.*]], align 4
830
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[VALX]], [[VALY]]
831
+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_EQ:%.*]], label [[END:%.*]]
832
+ ; CHECK: if.eq:
833
+ ; CHECK-NEXT: br label [[END]]
834
+ ; CHECK: end:
835
+ ; CHECK-NEXT: ret void
836
+ ;
837
+ entry:
838
+ %valx = load i32 , ptr %x , align 4
839
+ %valy = load i32 , ptr %y , align 4
840
+ %cmp = icmp eq i32 %valx , %valy
841
+ br i1 %cmp , label %if.eq , label %end
842
+
843
+ if.eq:
844
+ store i32 %valy , ptr %x , align 4
845
+ br label %end
846
+
847
+ end:
848
+ ret void
849
+ }
850
+
851
+ ; Dominating condition implies value already exists, optimize store
852
+ define void @remove_tautological_store_ne (ptr %x ) {
853
+ ; CHECK-LABEL: @remove_tautological_store_ne(
854
+ ; CHECK-NEXT: entry:
855
+ ; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[X:%.*]], align 4
856
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[VAL]], 4
857
+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_NE:%.*]], label [[END:%.*]]
858
+ ; CHECK: if.ne:
859
+ ; CHECK-NEXT: br label [[END]]
860
+ ; CHECK: end:
861
+ ; CHECK-NEXT: ret void
862
+ ;
863
+ entry:
864
+ %val = load i32 , ptr %x , align 4
865
+ %cmp = icmp ne i32 %val , 4
866
+ br i1 %cmp , label %if.ne , label %end
867
+
868
+ if.ne:
869
+ br label %end
870
+
871
+ end:
872
+ store i32 4 , ptr %x , align 4
873
+ ret void
874
+ }
875
+
876
+ ; Dominating condition implies value already exists, optimize store
877
+ ; Optimizes unordered atomic stores
878
+ define void @remove_tautological_store_atomic_unordered (ptr %x ) {
879
+ ; CHECK-LABEL: @remove_tautological_store_atomic_unordered(
880
+ ; CHECK-NEXT: entry:
881
+ ; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[X:%.*]], align 4
882
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[VAL]], 4
883
+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_EQ:%.*]], label [[END:%.*]]
884
+ ; CHECK: if.eq:
885
+ ; CHECK-NEXT: br label [[END]]
886
+ ; CHECK: end:
887
+ ; CHECK-NEXT: ret void
888
+ ;
889
+ entry:
890
+ %val = load i32 , ptr %x , align 4
891
+ %cmp = icmp eq i32 %val , 4
892
+ br i1 %cmp , label %if.eq , label %end
893
+
894
+ if.eq:
895
+ store atomic i32 4 , ptr %x unordered , align 4
896
+ br label %end
897
+
898
+ end:
899
+ ret void
900
+ }
901
+
902
+ ; Dominating condition implies value already exists, optimize store
903
+ ; Should not optimize ordered atomic stores
904
+ define void @remove_tautological_store_atomic_monotonic (ptr %x ) {
905
+ ; CHECK-LABEL: @remove_tautological_store_atomic_monotonic(
906
+ ; CHECK-NEXT: entry:
907
+ ; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[X:%.*]], align 4
908
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[VAL]], 4
909
+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_EQ:%.*]], label [[END:%.*]]
910
+ ; CHECK: if.eq:
911
+ ; CHECK-NEXT: store atomic i32 4, ptr [[X]] monotonic, align 4
912
+ ; CHECK-NEXT: br label [[END]]
913
+ ; CHECK: end:
914
+ ; CHECK-NEXT: ret void
915
+ ;
916
+ entry:
917
+ %val = load i32 , ptr %x , align 4
918
+ %cmp = icmp eq i32 %val , 4
919
+ br i1 %cmp , label %if.eq , label %end
920
+
921
+ if.eq:
922
+ store atomic i32 4 , ptr %x monotonic , align 4
923
+ br label %end
924
+
925
+ end:
926
+ ret void
927
+ }
928
+
929
+ ; Dominating condition implies value already exists, optimize store
930
+ ; Should not optimize since the store is in incorrect branch
931
+ define void @remove_tautological_store_eq_wrong_branch (ptr %x , ptr %y ) {
932
+ ; CHECK-LABEL: @remove_tautological_store_eq_wrong_branch(
933
+ ; CHECK-NEXT: entry:
934
+ ; CHECK-NEXT: [[VALX:%.*]] = load i32, ptr [[X:%.*]], align 4
935
+ ; CHECK-NEXT: [[VALY:%.*]] = load i32, ptr [[Y:%.*]], align 4
936
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[VALX]], [[VALY]]
937
+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_EQ:%.*]], label [[END:%.*]]
938
+ ; CHECK: if.eq:
939
+ ; CHECK-NEXT: br label [[END]]
940
+ ; CHECK: end:
941
+ ; CHECK-NEXT: store i32 [[VALY]], ptr [[X]], align 4
942
+ ; CHECK-NEXT: ret void
943
+ ;
944
+ entry:
945
+ %valx = load i32 , ptr %x , align 4
946
+ %valy = load i32 , ptr %y , align 4
947
+ %cmp = icmp eq i32 %valx , %valy
948
+ br i1 %cmp , label %if.eq , label %end
949
+
950
+ if.eq:
951
+ br label %end
952
+
953
+ end:
954
+ store i32 %valy , ptr %x , align 4
955
+ ret void
956
+ }
957
+
958
+ ; Dominating condition implies value already exists, optimize store
959
+ ; Should not optimize since the store is in incorrect branch
960
+ define void @remove_tautological_store_ne_wrong_branch (ptr %x ) {
961
+ ; CHECK-LABEL: @remove_tautological_store_ne_wrong_branch(
962
+ ; CHECK-NEXT: entry:
963
+ ; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[X:%.*]], align 4
964
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[VAL]], 4
965
+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_NE:%.*]], label [[END:%.*]]
966
+ ; CHECK: if.ne:
967
+ ; CHECK-NEXT: store i32 4, ptr [[X]], align 4
968
+ ; CHECK-NEXT: br label [[END]]
969
+ ; CHECK: end:
970
+ ; CHECK-NEXT: ret void
971
+ ;
972
+ entry:
973
+ %val = load i32 , ptr %x , align 4
974
+ %cmp = icmp ne i32 %val , 4
975
+ br i1 %cmp , label %if.ne , label %end
976
+
977
+ if.ne:
978
+ store i32 4 , ptr %x , align 4
979
+ br label %end
980
+
981
+ end:
982
+ ret void
983
+ }
984
+
985
+ ; Dominating condition implies value already exists, optimize store
986
+ ; Should not optimize since we cannot determine if we should when both
987
+ ; branches are the same
988
+ define void @remove_tautological_store_same_branch (ptr %x ) {
989
+ ; CHECK-LABEL: @remove_tautological_store_same_branch(
990
+ ; CHECK-NEXT: entry:
991
+ ; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[X:%.*]], align 4
992
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[VAL]], 4
993
+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_EQ:%.*]], label [[IF_EQ]]
994
+ ; CHECK: if.eq:
995
+ ; CHECK-NEXT: store i32 4, ptr [[X]], align 4
996
+ ; CHECK-NEXT: br label [[END:%.*]]
997
+ ; CHECK: end:
998
+ ; CHECK-NEXT: ret void
999
+ ;
1000
+ entry:
1001
+ %val = load i32 , ptr %x , align 4
1002
+ %cmp = icmp eq i32 %val , 4
1003
+ br i1 %cmp , label %if.eq , label %if.eq
1004
+
1005
+ if.eq:
1006
+ store i32 4 , ptr %x , align 4
1007
+ br label %end
1008
+
1009
+ end:
1010
+ ret void
1011
+ }
1012
+
1013
+ ; Dominating condition implies value already exists, optimize store
1014
+ ; Should not optimize since value being stored is different from cond check
1015
+ define void @remove_tautological_store_wrong_value (ptr %x ) {
1016
+ ; CHECK-LABEL: @remove_tautological_store_wrong_value(
1017
+ ; CHECK-NEXT: entry:
1018
+ ; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[X:%.*]], align 4
1019
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[VAL]], 4
1020
+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_EQ:%.*]], label [[END:%.*]]
1021
+ ; CHECK: if.eq:
1022
+ ; CHECK-NEXT: store i32 5, ptr [[X]], align 4
1023
+ ; CHECK-NEXT: br label [[END]]
1024
+ ; CHECK: end:
1025
+ ; CHECK-NEXT: ret void
1026
+ ;
1027
+ entry:
1028
+ %val = load i32 , ptr %x , align 4
1029
+ %cmp = icmp eq i32 %val , 4
1030
+ br i1 %cmp , label %if.eq , label %end
1031
+
1032
+ if.eq:
1033
+ store i32 5 , ptr %x , align 4
1034
+ br label %end
1035
+
1036
+ end:
1037
+ ret void
1038
+ }
1039
+
1040
+ ; Dominating condition implies value already exists, optimize store
1041
+ ; Should not optimize since there is a clobbering acc after load
1042
+ define void @remove_tautological_store_clobber (ptr %x ) {
1043
+ ; CHECK-LABEL: @remove_tautological_store_clobber(
1044
+ ; CHECK-NEXT: entry:
1045
+ ; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[X:%.*]], align 4
1046
+ ; CHECK-NEXT: store i32 5, ptr [[X]], align 4
1047
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[VAL]], 4
1048
+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_EQ:%.*]], label [[END:%.*]]
1049
+ ; CHECK: if.eq:
1050
+ ; CHECK-NEXT: store i32 4, ptr [[X]], align 4
1051
+ ; CHECK-NEXT: br label [[END]]
1052
+ ; CHECK: end:
1053
+ ; CHECK-NEXT: ret void
1054
+ ;
1055
+ entry:
1056
+ %val = load i32 , ptr %x , align 4
1057
+ store i32 5 , ptr %x , align 4
1058
+ %cmp = icmp eq i32 %val , 4
1059
+ br i1 %cmp , label %if.eq , label %end
1060
+
1061
+ if.eq:
1062
+ store i32 4 , ptr %x , align 4
1063
+ br label %end
1064
+
1065
+ end:
1066
+ ret void
1067
+ }
1068
+
1069
+ ; Dominating condition implies value already exists, optimize store
1070
+ ; Should not optimize since the condition does not dominate the store
1071
+ define void @remove_tautological_store_no_dom (ptr %x ) {
1072
+ ; CHECK-LABEL: @remove_tautological_store_no_dom(
1073
+ ; CHECK-NEXT: entry:
1074
+ ; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[X:%.*]], align 4
1075
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[VAL]], 4
1076
+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_EQ:%.*]], label [[IF_ELSE:%.*]]
1077
+ ; CHECK: if.eq:
1078
+ ; CHECK-NEXT: br label [[END:%.*]]
1079
+ ; CHECK: if.else:
1080
+ ; CHECK-NEXT: br label [[END]]
1081
+ ; CHECK: end:
1082
+ ; CHECK-NEXT: store i32 4, ptr [[X]], align 4
1083
+ ; CHECK-NEXT: ret void
1084
+ ;
1085
+ entry:
1086
+ %val = load i32 , ptr %x , align 4
1087
+ store i32 5 , ptr %x , align 4
1088
+ %cmp = icmp eq i32 %val , 4
1089
+ br i1 %cmp , label %if.eq , label %if.else
1090
+
1091
+ if.eq:
1092
+ br label %end
1093
+
1094
+ if.else:
1095
+ br label %end
1096
+
1097
+ end:
1098
+ store i32 4 , ptr %x , align 4
1099
+ ret void
1100
+ }
1101
+
1102
+ ; Dominating condition implies value already exists, optimize store
1103
+ ; Should not optimize volatile stores
1104
+ define void @remove_tautological_store_volatile (ptr %x ) {
1105
+ ; CHECK-LABEL: @remove_tautological_store_volatile(
1106
+ ; CHECK-NEXT: entry:
1107
+ ; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[X:%.*]], align 4
1108
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[VAL]], 4
1109
+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_EQ:%.*]], label [[END:%.*]]
1110
+ ; CHECK: if.eq:
1111
+ ; CHECK-NEXT: store volatile i32 4, ptr [[X]], align 4
1112
+ ; CHECK-NEXT: br label [[END]]
1113
+ ; CHECK: end:
1114
+ ; CHECK-NEXT: ret void
1115
+ ;
1116
+ entry:
1117
+ %val = load i32 , ptr %x , align 4
1118
+ %cmp = icmp eq i32 %val , 4
1119
+ br i1 %cmp , label %if.eq , label %end
1120
+
1121
+ if.eq:
1122
+ store volatile i32 4 , ptr %x , align 4
1123
+ br label %end
1124
+
1125
+ end:
1126
+ ret void
1127
+ }
0 commit comments