-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[InferAddressSpaces] Fix bad addrspacecast insertion for phinode
#163528
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 | ||
| ; RUN: opt -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -S -passes='require<domtree>,infer-address-spaces' %s | FileCheck %s | ||
|
|
||
| define void @test(ptr %lhs_ptr, ptr %rhs_ptr) { | ||
| ; CHECK-LABEL: define void @test( | ||
| ; CHECK-SAME: ptr [[LHS_PTR:%.*]], ptr [[RHS_PTR:%.*]]) #[[ATTR0:[0-9]+]] { | ||
| ; CHECK-NEXT: [[ENTRY:.*:]] | ||
| ; CHECK-NEXT: [[PTR_1:%.*]] = load ptr, ptr [[LHS_PTR]], align 8 | ||
| ; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr [[PTR_1]] to ptr addrspace(3) | ||
| ; CHECK-NEXT: [[BOOL_1:%.*]] = tail call i1 @llvm.amdgcn.is.shared(ptr [[PTR_1]]) | ||
| ; CHECK-NEXT: tail call void @llvm.assume(i1 [[BOOL_1]]) | ||
| ; CHECK-NEXT: [[PTR_2:%.*]] = load ptr, ptr [[RHS_PTR]], align 8 | ||
| ; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[PTR_2]] to ptr addrspace(3) | ||
| ; CHECK-NEXT: [[BOOL_2:%.*]] = tail call i1 @llvm.amdgcn.is.shared(ptr [[PTR_2]]) | ||
| ; CHECK-NEXT: tail call void @llvm.assume(i1 [[BOOL_2]]) | ||
| ; CHECK-NEXT: br i1 poison, label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] | ||
| ; CHECK: [[IF_THEN]]: | ||
| ; CHECK-NEXT: [[V1:%.*]] = load i32, ptr null, align 4 | ||
| ; CHECK-NEXT: br label %[[IF_SINK_SPLIT:.*]] | ||
| ; CHECK: [[IF_ELSE]]: | ||
| ; CHECK-NEXT: [[V2:%.*]] = load i32, ptr null, align 4 | ||
| ; CHECK-NEXT: br label %[[IF_SINK_SPLIT]] | ||
| ; CHECK: [[IF_SINK_SPLIT]]: | ||
| ; CHECK-NEXT: [[PTR_SINK:%.*]] = phi ptr addrspace(3) [ [[TMP0]], %[[IF_THEN]] ], [ [[TMP1]], %[[IF_ELSE]] ] | ||
| ; CHECK-NEXT: [[V_SINK:%.*]] = phi i32 [ [[V1]], %[[IF_THEN]] ], [ [[V2]], %[[IF_ELSE]] ] | ||
| ; CHECK-NEXT: store i32 [[V_SINK]], ptr addrspace(3) [[PTR_SINK]], align 4 | ||
| ; CHECK-NEXT: ret void | ||
| ; | ||
| entry: | ||
| %ptr.1 = load ptr, ptr %lhs_ptr, align 8 | ||
| %bool.1 = tail call i1 @llvm.amdgcn.is.shared(ptr %ptr.1) | ||
| tail call void @llvm.assume(i1 %bool.1) | ||
|
|
||
| %ptr.2 = load ptr, ptr %rhs_ptr, align 8 | ||
| %bool.2 = tail call i1 @llvm.amdgcn.is.shared(ptr %ptr.2) | ||
| tail call void @llvm.assume(i1 %bool.2) | ||
| br i1 poison, label %if.then, label %if.else | ||
|
|
||
| if.then: ; preds = %entry | ||
| %v1 = load i32, ptr null, align 4 | ||
| br label %if.sink.split | ||
|
|
||
| if.else: ; preds = %entry | ||
| %v2 = load i32, ptr null, align 4 | ||
| br label %if.sink.split | ||
|
|
||
| if.sink.split: ; preds = %if.else, %if.then | ||
| %ptr.sink = phi ptr [ %ptr.1, %if.then ], [ %ptr.2, %if.else ] | ||
| %v.sink = phi i32 [ %v1, %if.then ], [ %v2, %if.else ] | ||
| store i32 %v.sink, ptr %ptr.sink, align 4 | ||
| ret void | ||
| } | ||
|
|
||
| declare void @llvm.assume(i1 noundef) | ||
| declare i1 @llvm.amdgcn.is.shared(ptr) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | ||
| ; RUN: opt -S -passes='require<domtree>,infer-address-spaces' %s | FileCheck %s | ||
|
|
||
| ;;; Handle write corner case for infer-address-spaces with phi-nodes. The | ||
| ;;; verifier will crash if we insert `addrspacecast` before phi-node. | ||
|
|
||
| target triple = "nvptx64-nvidia-cuda" | ||
|
||
|
|
||
| declare void @llvm.assume(i1 noundef) | ||
| declare i1 @llvm.nvvm.isspacep.shared(ptr) | ||
| declare i1 @llvm.nvvm.isspacep.global(ptr) | ||
|
|
||
| define void @phinode_instr() { | ||
| ; CHECK-LABEL: @phinode_instr( | ||
| ; CHECK-NEXT: entry: | ||
| ; CHECK-NEXT: [[PTR_1:%.*]] = load ptr, ptr null, align 8 | ||
| ; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr [[PTR_1]] to ptr addrspace(3) | ||
| ; CHECK-NEXT: [[BOOL_1:%.*]] = tail call i1 @llvm.nvvm.isspacep.shared(ptr [[PTR_1]]) | ||
| ; CHECK-NEXT: tail call void @llvm.assume(i1 [[BOOL_1]]) | ||
| ; CHECK-NEXT: br label [[IF_SINK_SPLIT:%.*]] | ||
| ; CHECK: if.sink.split: | ||
| ; CHECK-NEXT: [[PTR_SINK:%.*]] = phi ptr addrspace(3) [ [[TMP0]], [[ENTRY:%.*]] ] | ||
| ; CHECK-NEXT: store i32 1, ptr addrspace(3) [[PTR_SINK]], align 4 | ||
| ; CHECK-NEXT: ret void | ||
| ; | ||
| entry: | ||
| %ptr.1 = load ptr, ptr null, align 8 | ||
| %bool.1 = tail call i1 @llvm.nvvm.isspacep.shared(ptr %ptr.1) | ||
| tail call void @llvm.assume(i1 %bool.1) | ||
| br label %if.sink.split | ||
|
|
||
| if.sink.split: ; preds = %entry | ||
| %ptr.sink = phi ptr [ %ptr.1, %entry ] | ||
| store i32 1, ptr %ptr.sink, align 4 | ||
| ret void | ||
| } | ||
|
|
||
| define void @phinode_argument(ptr %lhs_ptr) { | ||
| ; CHECK-LABEL: @phinode_argument( | ||
| ; CHECK-NEXT: entry: | ||
| ; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr [[LHS_PTR:%.*]] to ptr addrspace(1) | ||
| ; CHECK-NEXT: [[BOOL_1:%.*]] = tail call i1 @llvm.nvvm.isspacep.global(ptr [[LHS_PTR]]) | ||
| ; CHECK-NEXT: tail call void @llvm.assume(i1 [[BOOL_1]]) | ||
| ; CHECK-NEXT: br label [[IF_SINK_SPLIT:%.*]] | ||
| ; CHECK: if.sink.split: | ||
| ; CHECK-NEXT: [[PTR_SINK:%.*]] = phi ptr addrspace(1) [ [[TMP0]], [[ENTRY:%.*]] ] | ||
| ; CHECK-NEXT: store i32 1, ptr addrspace(1) [[PTR_SINK]], align 4 | ||
| ; CHECK-NEXT: ret void | ||
| ; | ||
| entry: | ||
| %bool.1 = tail call i1 @llvm.nvvm.isspacep.global(ptr %lhs_ptr) | ||
| tail call void @llvm.assume(i1 %bool.1) | ||
| br label %if.sink.split | ||
|
|
||
| if.sink.split: ; preds = %entry | ||
| %ptr.sink = phi ptr [ %lhs_ptr, %entry ] | ||
| store i32 1, ptr %ptr.sink, align 4 | ||
| ret void | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be simpler to just insert the new instruction before the terminator instruction in the incoming BB, so that we don't care the Operand is Argument, Constant, Phi or Instruction.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is quite simple to insert new cast instructions in every incoming BB, but on the other hand, it seems a bit redundant.
The preferred insertion point for new cast instructions is the dominator BB. However, this approach would require significant refactoring of current code.