[PATCH] D72048: [InstCombine] Preserve nuw on sub of geps (PR44419)
Roman Lebedev via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 1 03:53:38 PST 2020
lebedev.ri added a comment.
In D72048#1800331 <https://reviews.llvm.org/D72048#1800331>, @nikic wrote:
> I think this is still not quite right for the case where there are multiple GEP indexes. For example:
>
> define i64 @test_inbounds_nuw_multi_index([0 x [2 x i32]]* %base, i64 %idx, i64 %idx2) {
> ; CHECK-LABEL: @test_inbounds_nuw_multi_index(
> ; CHECK-NEXT: [[P2_IDX:%.*]] = shl nuw nsw i64 [[IDX:%.*]], 3
> ; CHECK-NEXT: [[P2_IDX1:%.*]] = shl nuw nsw i64 [[IDX2:%.*]], 2
> ; CHECK-NEXT: [[P2_OFFS2:%.*]] = add i64 [[P2_IDX]], [[P2_IDX1]]
> ; CHECK-NEXT: ret i64 [[P2_OFFS2]]
> ;
> %p1 = getelementptr inbounds [0 x [2 x i32]], [0 x [2 x i32]]* %base, i64 0, i64 0, i64 0
> %p2 = getelementptr inbounds [0 x [2 x i32]], [0 x [2 x i32]]* %base, i64 0, i64 %idx, i64 %idx2
> %i1 = ptrtoint i32* %p1 to i64
> %i2 = ptrtoint i32* %p2 to i64
> %d = sub nuw i64 %i2, %i1
> ret i64 %d
> }
>
>
> Let's say %idx=-1, %idx2=4, then the overall result is `8 * %idx1 + 4 * %idx2 = 8`, which is positive, even though one of the intermediate indexes is negative and as such can't use `shl nuw`. I think in this case the `nuw` can't be on any of the instructions (including also not the `add`). Right?
Sure.
----------------------------------------
define i64 @test_inbounds_nuw_multi_index(* %base, i64 %idx, i64 %idx2) {
%0:
%p1 = gep inbounds * %base, 0 x i64 0, 8 x i64 0, 4 x i64 0
%p2 = gep inbounds * %base, 0 x i64 0, 8 x i64 %idx, 4 x i64 %idx2
%i1 = ptrtoint * %p1 to i64
%i2 = ptrtoint * %p2 to i64
%d = sub nuw i64 %i2, %i1
ret i64 %d
}
=>
define i64 @test_inbounds_nuw_multi_index(* %base, i64 %idx, i64 %idx2) {
%0:
%P2_IDX = shl nsw nuw i64 %idx, 3
%P2_IDX1 = shl nsw nuw i64 %idx2, 2
%P2_OFFS2 = add i64 %P2_IDX, %P2_IDX1
ret i64 %P2_OFFS2
}
Transformation doesn't verify!
ERROR: Target is more poisonous than source
Example:
* %base = pointer(non-local, block_id=1, offset=498773658766409739)
i64 %idx = #x0322800007800000 (225883668936130560)
i64 %idx2 = #xfa00000000000000 (18014398509481984000, -432345564227567616)
Source:
* %p1 = pointer(non-local, block_id=1, offset=498773658766409739)
* %p2 = pointer(non-local, block_id=1, offset=576460753345183755)
i64 %i1 = #x171bffffc3ffffff (1665205961213607935)
i64 %i2 = #x182fffffffffffff (1742893055792381951)
i64 %d = #x011400003c000000 (77687094578774016)
Target:
i64 %P2_IDX = #x191400003c000000 (1807069351489044480)
i64 %P2_IDX1 = poison
i64 %P2_OFFS2 = poison
Source value: #x011400003c000000 (77687094578774016)
Target value: poison
Summary:
0 correct transformations
1 incorrect transformations
0 errors
----------------------------------------
define i64 @test_inbounds_nuw_multi_index(* %base, i64 %idx, i64 %idx2) {
%0:
%p1 = gep inbounds * %base, 0 x i64 0, 8 x i64 0, 4 x i64 0
%p2 = gep inbounds * %base, 0 x i64 0, 8 x i64 %idx, 4 x i64 %idx2
%i1 = ptrtoint * %p1 to i64
%i2 = ptrtoint * %p2 to i64
%d = sub nuw i64 %i2, %i1
ret i64 %d
}
=>
define i64 @test_inbounds_nuw_multi_index(* %base, i64 %idx, i64 %idx2) {
%0:
%P2_IDX = shl nsw i64 %idx, 3
%P2_IDX1 = shl nsw i64 %idx2, 2
%P2_OFFS2 = add i64 %P2_IDX, %P2_IDX1
ret i64 %P2_OFFS2
}
Transformation seems to be correct!
Summary:
1 correct transformations
0 incorrect transformations
0 errors
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D72048/new/
https://reviews.llvm.org/D72048
More information about the llvm-commits
mailing list