Changeset View
Standalone View
llvm/test/Transforms/CallSiteSplitting/callsite-split-callbr.ll
- This file was added.
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | |||||
; RUN: opt -callsite-splitting -S -o - < %s | FileCheck %s | |||||
; Check that we can split the critical edge between Top and CallSiteBB, and | |||||
; rewrite the first callbr's indirect destination correctly. | |||||
define void @caller() { | |||||
; CHECK-LABEL: @caller( | |||||
; CHECK-NEXT: Top: | |||||
; CHECK-NEXT: callbr void asm sideeffect "", "X,~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@caller, [[TOP_SPLIT:%.*]])) | |||||
; CHECK-NEXT: to label [[NEXTCOND:%.*]] [label %Top.split] | |||||
; CHECK: Top.split: | |||||
; CHECK-NEXT: call void @callee(i1 false) | |||||
nickdesaulniers: noob question: this totally fails for me, even though the test was autogenerated. FileCheck is… | |||||
voidUnsubmitted FileCheck should ignore the comment...Try changing CHECK: Top.split: to CHECK-LABEL: Top.split: or add the comment? void: FileCheck should ignore the comment...Try changing
```
CHECK: Top.split:
```
to
```
CHECK… | |||||
nickdesaulniersAuthorUnsubmitted That works, thanks @void! update_test_checks.py tries to change them back though... nickdesaulniers: That works, thanks @void!
update_test_checks.py tries to change them back though... | |||||
; CHECK-NEXT: br label [[CALLSITEBB:%.*]] | |||||
; CHECK: NextCond: | |||||
; CHECK-NEXT: br label [[NEXTCOND_SPLIT:%.*]] | |||||
; CHECK: NextCond.split: | |||||
; CHECK-NEXT: call void @callee(i1 true) | |||||
; CHECK-NEXT: br label [[CALLSITEBB]] | |||||
; CHECK: CallSiteBB: | |||||
; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ false, [[TOP_SPLIT]] ], [ true, [[NEXTCOND_SPLIT]] ] | |||||
; CHECK-NEXT: callbr void asm sideeffect "", "r,X,~{dirflag},~{fpsr},~{flags}"(i1 [[PHI]], i8* blockaddress(@caller, [[END2:%.*]])) | |||||
; CHECK-NEXT: to label [[END:%.*]] [label %End2] | |||||
nickdesaulniersAuthorUnsubmitted Not Done ReplyInline ActionsNote that update_test_checks.py rewrites the label references, but seemingly not for the indirect label list... nickdesaulniers: Note that `update_test_checks.py` rewrites the label references, but seemingly not for the… | |||||
; CHECK: End: | |||||
; CHECK-NEXT: ret void | |||||
; CHECK: End2: | |||||
; CHECK-NEXT: ret void | |||||
; | |||||
Top: | |||||
callbr void asm sideeffect "", "X,~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@caller, %CallSiteBB)) | |||||
to label %NextCond [label %CallSiteBB] | |||||
NextCond: | |||||
br label %CallSiteBB | |||||
CallSiteBB: | |||||
%phi = phi i1 [0, %Top],[1, %NextCond] | |||||
call void @callee(i1 %phi) | |||||
callbr void asm sideeffect "", "r,X,~{dirflag},~{fpsr},~{flags}"(i1 %phi, i8* blockaddress(@caller, %End2)) | |||||
to label %End [label %End2] | |||||
Not Done ReplyInline ActionsDoes callbr always take the destinations as blockaddress or could an arbitrary i8* value be used? Then doing the splitting here would only be safe if we can update the blockaddress constant and not in other cases I think. fhahn: Does `callbr` always take the destinations as `blockaddress` or could an arbitrary `i8*` value… | |||||
Not Done ReplyInline ActionsYes; always blockaddresses. @efriedma and I have discussed removing the duplication in callbr; the indirect destination list ([label %End2]) duplicates the arguments to the inline asm (blockaddress(@caller, %End2). This is an invariant that is checked by IR verification. (Using grammar from https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html) But the duplication is brittle because while setSuccessor does work correctly, the lower level setOperand does not update callbr operands correctly. It's also hard to distinguish between the labels passed in for asm goto vs extended inline asm inputs that are labels, ex foo: asm goto (""::"r"(foo)::bar); bar:; (we know bar is a potential destination, but provide no guarantees that foo can be safely jumped to from the inline asm. (InputOperands vs GotoLabels) Removing the duplication should fix that brittleness, but it's also orthogonal to this patch. Only blockaddresses can be indirect destinations that we preserve. Arbitrary addresses can be arguments to inline asm (InputOperands), but we provide no guarantees unless the label in in the final inline asm parameter list (GotoLabels), as opposed to the list of inputs (InputOperands). nickdesaulniers: Yes; always `blockaddress`es. @efriedma and I have discussed removing the duplication in… | |||||
End: | |||||
ret void | |||||
End2: | |||||
ret void | |||||
} | |||||
define void @callee(i1 %b) { | |||||
; CHECK-LABEL: @callee( | |||||
; CHECK-NEXT: ret void | |||||
; | |||||
ret void | |||||
} |
noob question: this totally fails for me, even though the test was autogenerated. FileCheck is complaining that:
which makes no sense to me. Am I holding it wrong?