@@ -6054,3 +6054,189 @@ define i1 @icmp_samesign_logical_or(i32 %In) {
60546054 %V = select i1 %c1 , i1 true , i1 %c2
60556055 ret i1 %V
60566056}
6057+
6058+ define i1 @non_zero_ptrdiff_implies_icmp_eq (ptr %p0 , ptr %p1 ) {
6059+ ; CHECK-LABEL: define i1 @non_zero_ptrdiff_implies_icmp_eq(
6060+ ; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {
6061+ ; CHECK-NEXT: [[ENTRY:.*:]]
6062+ ; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i64
6063+ ; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i64
6064+ ; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]
6065+ ; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[DIFF]], 12
6066+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
6067+ ; CHECK-NEXT: ret i1 false
6068+ ;
6069+ entry:
6070+ %i0 = ptrtoint ptr %p0 to i64
6071+ %i1 = ptrtoint ptr %p1 to i64
6072+ %diff = sub i64 %i0 , %i1
6073+ %cond = icmp eq i64 %diff , 12
6074+ call void @llvm.assume (i1 %cond )
6075+ %cmp = icmp eq ptr %p0 , %p1
6076+ ret i1 %cmp
6077+ }
6078+
6079+ define i1 @non_zero_ptrdiff_implies_icmp_eq_commuted (ptr %p0 , ptr %p1 ) {
6080+ ; CHECK-LABEL: define i1 @non_zero_ptrdiff_implies_icmp_eq_commuted(
6081+ ; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {
6082+ ; CHECK-NEXT: [[ENTRY:.*:]]
6083+ ; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i64
6084+ ; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i64
6085+ ; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]
6086+ ; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[DIFF]], 12
6087+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
6088+ ; CHECK-NEXT: ret i1 false
6089+ ;
6090+ entry:
6091+ %i0 = ptrtoint ptr %p0 to i64
6092+ %i1 = ptrtoint ptr %p1 to i64
6093+ %diff = sub i64 %i0 , %i1
6094+ %cond = icmp eq i64 %diff , 12
6095+ call void @llvm.assume (i1 %cond )
6096+ %cmp = icmp eq ptr %p1 , %p0
6097+ ret i1 %cmp
6098+ }
6099+
6100+ define i1 @non_zero_ptrdiff_implies_icmp_ne (ptr %p0 , ptr %p1 ) {
6101+ ; CHECK-LABEL: define i1 @non_zero_ptrdiff_implies_icmp_ne(
6102+ ; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {
6103+ ; CHECK-NEXT: [[ENTRY:.*:]]
6104+ ; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i64
6105+ ; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i64
6106+ ; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]
6107+ ; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[DIFF]], 12
6108+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
6109+ ; CHECK-NEXT: ret i1 true
6110+ ;
6111+ entry:
6112+ %i0 = ptrtoint ptr %p0 to i64
6113+ %i1 = ptrtoint ptr %p1 to i64
6114+ %diff = sub i64 %i0 , %i1
6115+ %cond = icmp eq i64 %diff , 12
6116+ call void @llvm.assume (i1 %cond )
6117+ %cmp = icmp ne ptr %p0 , %p1
6118+ ret i1 %cmp
6119+ }
6120+
6121+ ; TODO: Handle this case if it is shown in real code.
6122+ define i1 @non_zero_truncated_ptrdiff_implies_icmp_ne (ptr %p0 , ptr %p1 ) {
6123+ ; CHECK-LABEL: define i1 @non_zero_truncated_ptrdiff_implies_icmp_ne(
6124+ ; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {
6125+ ; CHECK-NEXT: [[ENTRY:.*:]]
6126+ ; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[P0]] to i64
6127+ ; CHECK-NEXT: [[I0:%.*]] = trunc i64 [[TMP0]] to i8
6128+ ; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[P1]] to i64
6129+ ; CHECK-NEXT: [[I1:%.*]] = trunc i64 [[TMP1]] to i8
6130+ ; CHECK-NEXT: [[DIFF:%.*]] = sub i8 [[I0]], [[I1]]
6131+ ; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[DIFF]], 12
6132+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
6133+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[P0]], [[P1]]
6134+ ; CHECK-NEXT: ret i1 [[CMP]]
6135+ ;
6136+ entry:
6137+ %i0 = ptrtoint ptr %p0 to i8
6138+ %i1 = ptrtoint ptr %p1 to i8
6139+ %diff = sub i8 %i0 , %i1
6140+ %cond = icmp eq i8 %diff , 12
6141+ call void @llvm.assume (i1 %cond )
6142+ %cmp = icmp ne ptr %p0 , %p1
6143+ ret i1 %cmp
6144+ }
6145+
6146+ define i1 @non_zero_diff_implies_icmp_eq (i8 %p0 , i8 %p1 ) {
6147+ ; CHECK-LABEL: define i1 @non_zero_diff_implies_icmp_eq(
6148+ ; CHECK-SAME: i8 [[P0:%.*]], i8 [[P1:%.*]]) {
6149+ ; CHECK-NEXT: [[ENTRY:.*:]]
6150+ ; CHECK-NEXT: [[DIFF:%.*]] = sub i8 [[P0]], [[P1]]
6151+ ; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[DIFF]], 12
6152+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
6153+ ; CHECK-NEXT: ret i1 false
6154+ ;
6155+ entry:
6156+ %diff = sub i8 %p0 , %p1
6157+ %cond = icmp eq i8 %diff , 12
6158+ call void @llvm.assume (i1 %cond )
6159+ %cmp = icmp eq i8 %p0 , %p1
6160+ ret i1 %cmp
6161+ }
6162+
6163+ define i1 @non_zero_diff_implies_icmp_eq_commuted (i8 %p0 , i8 %p1 ) {
6164+ ; CHECK-LABEL: define i1 @non_zero_diff_implies_icmp_eq_commuted(
6165+ ; CHECK-SAME: i8 [[P0:%.*]], i8 [[P1:%.*]]) {
6166+ ; CHECK-NEXT: [[ENTRY:.*:]]
6167+ ; CHECK-NEXT: [[DIFF:%.*]] = sub i8 [[P0]], [[P1]]
6168+ ; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[DIFF]], 12
6169+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
6170+ ; CHECK-NEXT: ret i1 false
6171+ ;
6172+ entry:
6173+ %diff = sub i8 %p0 , %p1
6174+ %cond = icmp eq i8 %diff , 12
6175+ call void @llvm.assume (i1 %cond )
6176+ %cmp = icmp eq i8 %p1 , %p0
6177+ ret i1 %cmp
6178+ }
6179+
6180+ ; Negative tests
6181+
6182+ define i1 @unknown_ptrdiff_implies_icmp_eq1 (ptr %p0 , ptr %p1 ) {
6183+ ; CHECK-LABEL: define i1 @unknown_ptrdiff_implies_icmp_eq1(
6184+ ; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {
6185+ ; CHECK-NEXT: [[ENTRY:.*:]]
6186+ ; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i64
6187+ ; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i64
6188+ ; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]
6189+ ; CHECK-NEXT: [[COND:%.*]] = icmp ne i64 [[DIFF]], 12
6190+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
6191+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P0]], [[P1]]
6192+ ; CHECK-NEXT: ret i1 [[CMP]]
6193+ ;
6194+ entry:
6195+ %i0 = ptrtoint ptr %p0 to i64
6196+ %i1 = ptrtoint ptr %p1 to i64
6197+ %diff = sub i64 %i0 , %i1
6198+ %cond = icmp ne i64 %diff , 12
6199+ call void @llvm.assume (i1 %cond )
6200+ %cmp = icmp eq ptr %p0 , %p1
6201+ ret i1 %cmp
6202+ }
6203+
6204+ define i1 @unknown_ptrdiff_implies_icmp_eq2 (ptr %p0 , ptr %p1 , i64 %x ) {
6205+ ; CHECK-LABEL: define i1 @unknown_ptrdiff_implies_icmp_eq2(
6206+ ; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]], i64 [[X:%.*]]) {
6207+ ; CHECK-NEXT: [[ENTRY:.*:]]
6208+ ; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i64
6209+ ; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i64
6210+ ; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]
6211+ ; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[DIFF]], [[X]]
6212+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
6213+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P0]], [[P1]]
6214+ ; CHECK-NEXT: ret i1 [[CMP]]
6215+ ;
6216+ entry:
6217+ %i0 = ptrtoint ptr %p0 to i64
6218+ %i1 = ptrtoint ptr %p1 to i64
6219+ %diff = sub i64 %i0 , %i1
6220+ %cond = icmp eq i64 %diff , %x
6221+ call void @llvm.assume (i1 %cond )
6222+ %cmp = icmp eq ptr %p0 , %p1
6223+ ret i1 %cmp
6224+ }
6225+
6226+ define i1 @non_zero_diff_implies_icmp_ult (i8 %p0 , i8 %p1 ) {
6227+ ; CHECK-LABEL: define i1 @non_zero_diff_implies_icmp_ult(
6228+ ; CHECK-SAME: i8 [[P0:%.*]], i8 [[P1:%.*]]) {
6229+ ; CHECK-NEXT: [[ENTRY:.*:]]
6230+ ; CHECK-NEXT: [[DIFF:%.*]] = sub i8 [[P0]], [[P1]]
6231+ ; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[DIFF]], 12
6232+ ; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
6233+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[P0]], [[P1]]
6234+ ; CHECK-NEXT: ret i1 [[CMP]]
6235+ ;
6236+ entry:
6237+ %diff = sub i8 %p0 , %p1
6238+ %cond = icmp eq i8 %diff , 12
6239+ call void @llvm.assume (i1 %cond )
6240+ %cmp = icmp ult i8 %p0 , %p1
6241+ ret i1 %cmp
6242+ }
0 commit comments