@@ -981,3 +981,147 @@ define i1 @gep_multiple_multi_use_above_limit(ptr %base, i64 %idx1, i64 %idx2, i
981
981
%cmp = icmp eq ptr %gep4 , %base
982
982
ret i1 %cmp
983
983
}
984
+
985
+ define i1 @gep_gep_multiple_eq (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 , i64 %idx4 ) {
986
+ ; CHECK-LABEL: @gep_gep_multiple_eq(
987
+ ; CHECK-NEXT: [[GEP1_IDX1:%.*]] = add i64 [[IDX1:%.*]], [[IDX2:%.*]]
988
+ ; CHECK-NEXT: [[GEP3_IDX2:%.*]] = add i64 [[IDX3:%.*]], [[IDX4:%.*]]
989
+ ; CHECK-NEXT: [[CMP_UNSHIFTED:%.*]] = xor i64 [[GEP1_IDX1]], [[GEP3_IDX2]]
990
+ ; CHECK-NEXT: [[CMP_MASK:%.*]] = and i64 [[CMP_UNSHIFTED]], 4611686018427387903
991
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[CMP_MASK]], 0
992
+ ; CHECK-NEXT: ret i1 [[CMP]]
993
+ ;
994
+ %gep1 = getelementptr i32 , ptr %base , i64 %idx1
995
+ %gep2 = getelementptr i32 , ptr %gep1 , i64 %idx2
996
+ %gep3 = getelementptr i32 , ptr %base , i64 %idx3
997
+ %gep4 = getelementptr i32 , ptr %gep3 , i64 %idx4
998
+ %cmp = icmp eq ptr %gep2 , %gep4
999
+ ret i1 %cmp
1000
+ }
1001
+
1002
+ define i1 @gep_gep_multiple_eq_nuw (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 , i64 %idx4 ) {
1003
+ ; CHECK-LABEL: @gep_gep_multiple_eq_nuw(
1004
+ ; CHECK-NEXT: [[GEP1_IDX1:%.*]] = add i64 [[IDX1:%.*]], [[IDX2:%.*]]
1005
+ ; CHECK-NEXT: [[GEP3_IDX2:%.*]] = add i64 [[IDX3:%.*]], [[IDX4:%.*]]
1006
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[GEP1_IDX1]], [[GEP3_IDX2]]
1007
+ ; CHECK-NEXT: ret i1 [[CMP]]
1008
+ ;
1009
+ %gep1 = getelementptr nuw i32 , ptr %base , i64 %idx1
1010
+ %gep2 = getelementptr nuw i32 , ptr %gep1 , i64 %idx2
1011
+ %gep3 = getelementptr nuw i32 , ptr %base , i64 %idx3
1012
+ %gep4 = getelementptr nuw i32 , ptr %gep3 , i64 %idx4
1013
+ %cmp = icmp eq ptr %gep2 , %gep4
1014
+ ret i1 %cmp
1015
+ }
1016
+
1017
+ define i1 @gep_gep_multiple_eq_nuw_different_scales (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 , i64 %idx4 ) {
1018
+ ; CHECK-LABEL: @gep_gep_multiple_eq_nuw_different_scales(
1019
+ ; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw i64 [[IDX1:%.*]], 2
1020
+ ; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl nuw i64 [[IDX2:%.*]], 3
1021
+ ; CHECK-NEXT: [[TMP1:%.*]] = add nuw i64 [[GEP1_IDX]], [[GEP2_IDX]]
1022
+ ; CHECK-NEXT: [[GEP3_IDX:%.*]] = shl nuw i64 [[IDX3:%.*]], 2
1023
+ ; CHECK-NEXT: [[GEP4_IDX:%.*]] = shl nuw i64 [[IDX4:%.*]], 3
1024
+ ; CHECK-NEXT: [[TMP2:%.*]] = add nuw i64 [[GEP3_IDX]], [[GEP4_IDX]]
1025
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1]], [[TMP2]]
1026
+ ; CHECK-NEXT: ret i1 [[CMP]]
1027
+ ;
1028
+ %gep1 = getelementptr nuw i32 , ptr %base , i64 %idx1
1029
+ %gep2 = getelementptr nuw i64 , ptr %gep1 , i64 %idx2
1030
+ %gep3 = getelementptr nuw i32 , ptr %base , i64 %idx3
1031
+ %gep4 = getelementptr nuw i64 , ptr %gep3 , i64 %idx4
1032
+ %cmp = icmp eq ptr %gep2 , %gep4
1033
+ ret i1 %cmp
1034
+ }
1035
+
1036
+ define i1 @gep_gep_multiple_eq_partial_nuw_different_scales (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 , i64 %idx4 ) {
1037
+ ; CHECK-LABEL: @gep_gep_multiple_eq_partial_nuw_different_scales(
1038
+ ; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nuw i64 [[IDX1:%.*]], 2
1039
+ ; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl nuw i64 [[IDX2:%.*]], 3
1040
+ ; CHECK-NEXT: [[TMP1:%.*]] = add nuw i64 [[GEP1_IDX]], [[GEP2_IDX]]
1041
+ ; CHECK-NEXT: [[GEP3_IDX:%.*]] = shl nuw i64 [[IDX3:%.*]], 2
1042
+ ; CHECK-NEXT: [[GEP4_IDX:%.*]] = shl i64 [[IDX4:%.*]], 3
1043
+ ; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[GEP3_IDX]], [[GEP4_IDX]]
1044
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1]], [[TMP2]]
1045
+ ; CHECK-NEXT: ret i1 [[CMP]]
1046
+ ;
1047
+ %gep1 = getelementptr nuw i32 , ptr %base , i64 %idx1
1048
+ %gep2 = getelementptr nuw i64 , ptr %gep1 , i64 %idx2
1049
+ %gep3 = getelementptr nuw i32 , ptr %base , i64 %idx3
1050
+ %gep4 = getelementptr i64 , ptr %gep3 , i64 %idx4
1051
+ %cmp = icmp eq ptr %gep2 , %gep4
1052
+ ret i1 %cmp
1053
+ }
1054
+
1055
+ define i1 @gep_gep_multiple_eq_partial_inbounds_different_scales (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 , i64 %idx4 ) {
1056
+ ; CHECK-LABEL: @gep_gep_multiple_eq_partial_inbounds_different_scales(
1057
+ ; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[IDX1:%.*]], 2
1058
+ ; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl nsw i64 [[IDX2:%.*]], 3
1059
+ ; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[GEP1_IDX]], [[GEP2_IDX]]
1060
+ ; CHECK-NEXT: [[GEP3_IDX:%.*]] = shl nsw i64 [[IDX3:%.*]], 2
1061
+ ; CHECK-NEXT: [[GEP4_IDX:%.*]] = shl i64 [[IDX4:%.*]], 3
1062
+ ; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[GEP3_IDX]], [[GEP4_IDX]]
1063
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1]], [[TMP2]]
1064
+ ; CHECK-NEXT: ret i1 [[CMP]]
1065
+ ;
1066
+ %gep1 = getelementptr inbounds i32 , ptr %base , i64 %idx1
1067
+ %gep2 = getelementptr inbounds i64 , ptr %gep1 , i64 %idx2
1068
+ %gep3 = getelementptr inbounds i32 , ptr %base , i64 %idx3
1069
+ %gep4 = getelementptr i64 , ptr %gep3 , i64 %idx4
1070
+ %cmp = icmp eq ptr %gep2 , %gep4
1071
+ ret i1 %cmp
1072
+ }
1073
+
1074
+ define i1 @gep_gep_multiple_ult_nuw (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 , i64 %idx4 ) {
1075
+ ; CHECK-LABEL: @gep_gep_multiple_ult_nuw(
1076
+ ; CHECK-NEXT: [[GEP1_IDX1:%.*]] = add i64 [[IDX1:%.*]], [[IDX2:%.*]]
1077
+ ; CHECK-NEXT: [[GEP3_IDX2:%.*]] = add i64 [[IDX3:%.*]], [[IDX4:%.*]]
1078
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[GEP1_IDX1]], [[GEP3_IDX2]]
1079
+ ; CHECK-NEXT: ret i1 [[CMP]]
1080
+ ;
1081
+ %gep1 = getelementptr nuw i32 , ptr %base , i64 %idx1
1082
+ %gep2 = getelementptr nuw i32 , ptr %gep1 , i64 %idx2
1083
+ %gep3 = getelementptr nuw i32 , ptr %base , i64 %idx3
1084
+ %gep4 = getelementptr nuw i32 , ptr %gep3 , i64 %idx4
1085
+ %cmp = icmp ult ptr %gep2 , %gep4
1086
+ ret i1 %cmp
1087
+ }
1088
+
1089
+ define i1 @gep_gep_multiple_ult_missing_nuw (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 , i64 %idx4 ) {
1090
+ ; CHECK-LABEL: @gep_gep_multiple_ult_missing_nuw(
1091
+ ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr nuw i32, ptr [[BASE:%.*]], i64 [[IDX1:%.*]]
1092
+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nuw i32, ptr [[GEP1]], i64 [[IDX2:%.*]]
1093
+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr nuw i32, ptr [[BASE]], i64 [[IDX3:%.*]]
1094
+ ; CHECK-NEXT: [[GEP4:%.*]] = getelementptr i32, ptr [[GEP3]], i64 [[IDX4:%.*]]
1095
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[GEP2]], [[GEP4]]
1096
+ ; CHECK-NEXT: ret i1 [[CMP]]
1097
+ ;
1098
+ %gep1 = getelementptr nuw i32 , ptr %base , i64 %idx1
1099
+ %gep2 = getelementptr nuw i32 , ptr %gep1 , i64 %idx2
1100
+ %gep3 = getelementptr nuw i32 , ptr %base , i64 %idx3
1101
+ %gep4 = getelementptr i32 , ptr %gep3 , i64 %idx4
1102
+ %cmp = icmp ult ptr %gep2 , %gep4
1103
+ ret i1 %cmp
1104
+ }
1105
+
1106
+ define i1 @gep_gep_multiple_ult_nuw_multi_use (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 , i64 %idx4 ) {
1107
+ ; CHECK-LABEL: @gep_gep_multiple_ult_nuw_multi_use(
1108
+ ; CHECK-NEXT: [[IDX3:%.*]] = add i64 [[IDX1:%.*]], [[IDX2:%.*]]
1109
+ ; CHECK-NEXT: [[GEP3_IDX:%.*]] = shl nuw i64 [[IDX3]], 2
1110
+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr nuw i8, ptr [[BASE:%.*]], i64 [[GEP3_IDX]]
1111
+ ; CHECK-NEXT: [[IDX4:%.*]] = add i64 [[IDX5:%.*]], [[IDX6:%.*]]
1112
+ ; CHECK-NEXT: [[GEP4_IDX:%.*]] = shl nuw i64 [[IDX4]], 2
1113
+ ; CHECK-NEXT: [[GEP5:%.*]] = getelementptr nuw i8, ptr [[BASE]], i64 [[GEP4_IDX]]
1114
+ ; CHECK-NEXT: call void @use(ptr [[GEP3]])
1115
+ ; CHECK-NEXT: call void @use(ptr [[GEP5]])
1116
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[GEP3_IDX]], [[GEP4_IDX]]
1117
+ ; CHECK-NEXT: ret i1 [[CMP]]
1118
+ ;
1119
+ %gep1 = getelementptr nuw i32 , ptr %base , i64 %idx1
1120
+ %gep2 = getelementptr nuw i32 , ptr %gep1 , i64 %idx2
1121
+ %gep3 = getelementptr nuw i32 , ptr %base , i64 %idx3
1122
+ %gep4 = getelementptr nuw i32 , ptr %gep3 , i64 %idx4
1123
+ call void @use (ptr %gep2 )
1124
+ call void @use (ptr %gep4 )
1125
+ %cmp = icmp ult ptr %gep2 , %gep4
1126
+ ret i1 %cmp
1127
+ }
0 commit comments