@@ -981,3 +981,147 @@ 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_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