@@ -981,3 +981,143 @@ define i1 @gep_multiple_multi_use_above_limit(ptr %base, i64 %idx1, i64 %idx2, i
981981 %cmp = icmp eq ptr %gep4 , %base
982982 ret i1 %cmp
983983}
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:%.*]] = getelementptr i32, ptr [[BASE:%.*]], i64 [[IDX1:%.*]]
988+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i32, ptr [[GEP1]], i64 [[IDX2:%.*]]
989+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr i32, ptr [[BASE]], i64 [[IDX3:%.*]]
990+ ; CHECK-NEXT: [[GEP4:%.*]] = getelementptr i32, ptr [[GEP3]], i64 [[IDX4:%.*]]
991+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP2]], [[GEP4]]
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:%.*]] = getelementptr nuw i32, ptr [[BASE:%.*]], i64 [[IDX1:%.*]]
1005+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nuw i32, ptr [[GEP1]], i64 [[IDX2:%.*]]
1006+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr nuw i32, ptr [[BASE]], i64 [[IDX3:%.*]]
1007+ ; CHECK-NEXT: [[GEP4:%.*]] = getelementptr nuw i32, ptr [[GEP3]], i64 [[IDX4:%.*]]
1008+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP2]], [[GEP4]]
1009+ ; CHECK-NEXT: ret i1 [[CMP]]
1010+ ;
1011+ %gep1 = getelementptr nuw i32 , ptr %base , i64 %idx1
1012+ %gep2 = getelementptr nuw i32 , ptr %gep1 , i64 %idx2
1013+ %gep3 = getelementptr nuw i32 , ptr %base , i64 %idx3
1014+ %gep4 = getelementptr nuw i32 , ptr %gep3 , i64 %idx4
1015+ %cmp = icmp eq ptr %gep2 , %gep4
1016+ ret i1 %cmp
1017+ }
1018+
1019+ define i1 @gep_gep_multiple_eq_nuw_different_scales (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 , i64 %idx4 ) {
1020+ ; CHECK-LABEL: @gep_gep_multiple_eq_nuw_different_scales(
1021+ ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr nuw i32, ptr [[BASE:%.*]], i64 [[IDX1:%.*]]
1022+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nuw i64, ptr [[GEP1]], i64 [[IDX2:%.*]]
1023+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr nuw i32, ptr [[BASE]], i64 [[IDX3:%.*]]
1024+ ; CHECK-NEXT: [[GEP4:%.*]] = getelementptr nuw i64, ptr [[GEP3]], i64 [[IDX4:%.*]]
1025+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP2]], [[GEP4]]
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:%.*]] = getelementptr nuw i32, ptr [[BASE:%.*]], i64 [[IDX1:%.*]]
1039+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nuw i64, ptr [[GEP1]], i64 [[IDX2:%.*]]
1040+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr nuw i32, ptr [[BASE]], i64 [[IDX3:%.*]]
1041+ ; CHECK-NEXT: [[GEP4:%.*]] = getelementptr i64, ptr [[GEP3]], i64 [[IDX4:%.*]]
1042+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP2]], [[GEP4]]
1043+ ; CHECK-NEXT: ret i1 [[CMP]]
1044+ ;
1045+ %gep1 = getelementptr nuw i32 , ptr %base , i64 %idx1
1046+ %gep2 = getelementptr nuw i64 , ptr %gep1 , i64 %idx2
1047+ %gep3 = getelementptr nuw i32 , ptr %base , i64 %idx3
1048+ %gep4 = getelementptr i64 , ptr %gep3 , i64 %idx4
1049+ %cmp = icmp eq ptr %gep2 , %gep4
1050+ ret i1 %cmp
1051+ }
1052+
1053+ define i1 @gep_gep_multiple_eq_partial_inbounds_different_scales (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 , i64 %idx4 ) {
1054+ ; CHECK-LABEL: @gep_gep_multiple_eq_partial_inbounds_different_scales(
1055+ ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, ptr [[BASE:%.*]], i64 [[IDX1:%.*]]
1056+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i64, ptr [[GEP1]], i64 [[IDX2:%.*]]
1057+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr inbounds i32, ptr [[BASE]], i64 [[IDX3:%.*]]
1058+ ; CHECK-NEXT: [[GEP4:%.*]] = getelementptr i64, ptr [[GEP3]], i64 [[IDX4:%.*]]
1059+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP2]], [[GEP4]]
1060+ ; CHECK-NEXT: ret i1 [[CMP]]
1061+ ;
1062+ %gep1 = getelementptr inbounds i32 , ptr %base , i64 %idx1
1063+ %gep2 = getelementptr inbounds i64 , ptr %gep1 , i64 %idx2
1064+ %gep3 = getelementptr inbounds i32 , ptr %base , i64 %idx3
1065+ %gep4 = getelementptr i64 , ptr %gep3 , i64 %idx4
1066+ %cmp = icmp eq ptr %gep2 , %gep4
1067+ ret i1 %cmp
1068+ }
1069+
1070+ define i1 @gep_gep_multiple_ult_nuw (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 , i64 %idx4 ) {
1071+ ; CHECK-LABEL: @gep_gep_multiple_ult_nuw(
1072+ ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr nuw i32, ptr [[BASE:%.*]], i64 [[IDX1:%.*]]
1073+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nuw i32, ptr [[GEP1]], i64 [[IDX2:%.*]]
1074+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr nuw i32, ptr [[BASE]], i64 [[IDX3:%.*]]
1075+ ; CHECK-NEXT: [[GEP4:%.*]] = getelementptr nuw i32, ptr [[GEP3]], i64 [[IDX4:%.*]]
1076+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[GEP2]], [[GEP4]]
1077+ ; CHECK-NEXT: ret i1 [[CMP]]
1078+ ;
1079+ %gep1 = getelementptr nuw i32 , ptr %base , i64 %idx1
1080+ %gep2 = getelementptr nuw i32 , ptr %gep1 , i64 %idx2
1081+ %gep3 = getelementptr nuw i32 , ptr %base , i64 %idx3
1082+ %gep4 = getelementptr nuw i32 , ptr %gep3 , i64 %idx4
1083+ %cmp = icmp ult ptr %gep2 , %gep4
1084+ ret i1 %cmp
1085+ }
1086+
1087+ define i1 @gep_gep_multiple_ult_missing_nuw (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 , i64 %idx4 ) {
1088+ ; CHECK-LABEL: @gep_gep_multiple_ult_missing_nuw(
1089+ ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr nuw i32, ptr [[BASE:%.*]], i64 [[IDX1:%.*]]
1090+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nuw i32, ptr [[GEP1]], i64 [[IDX2:%.*]]
1091+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr nuw i32, ptr [[BASE]], i64 [[IDX3:%.*]]
1092+ ; CHECK-NEXT: [[GEP4:%.*]] = getelementptr i32, ptr [[GEP3]], i64 [[IDX4:%.*]]
1093+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[GEP2]], [[GEP4]]
1094+ ; CHECK-NEXT: ret i1 [[CMP]]
1095+ ;
1096+ %gep1 = getelementptr nuw i32 , ptr %base , i64 %idx1
1097+ %gep2 = getelementptr nuw i32 , ptr %gep1 , i64 %idx2
1098+ %gep3 = getelementptr nuw i32 , ptr %base , i64 %idx3
1099+ %gep4 = getelementptr i32 , ptr %gep3 , i64 %idx4
1100+ %cmp = icmp ult ptr %gep2 , %gep4
1101+ ret i1 %cmp
1102+ }
1103+
1104+ define i1 @gep_gep_multiple_ult_nuw_multi_use (ptr %base , i64 %idx1 , i64 %idx2 , i64 %idx3 , i64 %idx4 ) {
1105+ ; CHECK-LABEL: @gep_gep_multiple_ult_nuw_multi_use(
1106+ ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr nuw i32, ptr [[BASE:%.*]], i64 [[IDX1:%.*]]
1107+ ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nuw i32, ptr [[GEP1]], i64 [[IDX2:%.*]]
1108+ ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr nuw i32, ptr [[BASE]], i64 [[IDX3:%.*]]
1109+ ; CHECK-NEXT: [[GEP5:%.*]] = getelementptr nuw i32, ptr [[GEP3]], i64 [[IDX4:%.*]]
1110+ ; CHECK-NEXT: call void @use(ptr [[GEP2]])
1111+ ; CHECK-NEXT: call void @use(ptr [[GEP5]])
1112+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[GEP2]], [[GEP5]]
1113+ ; CHECK-NEXT: ret i1 [[CMP]]
1114+ ;
1115+ %gep1 = getelementptr nuw i32 , ptr %base , i64 %idx1
1116+ %gep2 = getelementptr nuw i32 , ptr %gep1 , i64 %idx2
1117+ %gep3 = getelementptr nuw i32 , ptr %base , i64 %idx3
1118+ %gep4 = getelementptr nuw i32 , ptr %gep3 , i64 %idx4
1119+ call void @use (ptr %gep2 )
1120+ call void @use (ptr %gep4 )
1121+ %cmp = icmp ult ptr %gep2 , %gep4
1122+ ret i1 %cmp
1123+ }
0 commit comments