| # RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu \ |
| # RUN: -start-before aarch64-speculation-hardening -o - %s \ |
| # RUN: | FileCheck %s --dump-input-on-failure |
| |
| # Check that the speculation hardening pass generates code as expected for |
| # basic blocks ending with a variety of branch patterns: |
| # - (1) no branches (fallthrough) |
| # - (2) one unconditional branch |
| # - (3) one conditional branch + fall-through |
| # - (4) one conditional branch + one unconditional branch |
| # - other direct branches don't seem to be generated by the AArch64 codegen |
| --- | |
| define void @nobranch_fallthrough(i32 %a, i32 %b) speculative_load_hardening { |
| ret void |
| } |
| define void @uncondbranch(i32 %a, i32 %b) speculative_load_hardening { |
| ret void |
| } |
| define void @condbranch_fallthrough(i32 %a, i32 %b) speculative_load_hardening { |
| ret void |
| } |
| define void @condbranch_uncondbranch(i32 %a, i32 %b) speculative_load_hardening { |
| ret void |
| } |
| define void @indirectbranch(i32 %a, i32 %b) speculative_load_hardening { |
| ret void |
| } |
| ... |
| --- |
| name: nobranch_fallthrough |
| tracksRegLiveness: true |
| body: | |
| ; CHECK-LABEL: nobranch_fallthrough |
| bb.0: |
| successors: %bb.1 |
| liveins: $w0, $w1 |
| ; CHECK-NOT: csel |
| bb.1: |
| liveins: $w0 |
| RET undef $lr, implicit $w0 |
| ... |
| --- |
| name: uncondbranch |
| tracksRegLiveness: true |
| body: | |
| ; CHECK-LABEL: uncondbranch |
| bb.0: |
| successors: %bb.1 |
| liveins: $w0, $w1 |
| B %bb.1 |
| ; CHECK-NOT: csel |
| bb.1: |
| liveins: $w0 |
| RET undef $lr, implicit $w0 |
| ... |
| --- |
| name: condbranch_fallthrough |
| tracksRegLiveness: true |
| body: | |
| ; CHECK-LABEL: condbranch_fallthrough |
| bb.0: |
| successors: %bb.1, %bb.2 |
| liveins: $w0, $w1 |
| $wzr = SUBSWrs renamable $w0, renamable $w1, 0, implicit-def $nzcv, implicit-def $nzcv |
| Bcc 11, %bb.2, implicit $nzcv |
| ; CHECK: b.lt [[BB_LT_T:\.LBB[0-9_]+]] |
| |
| bb.1: |
| liveins: $nzcv, $w0 |
| ; CHECK: csel x16, x16, xzr, ge |
| RET undef $lr, implicit $w0 |
| bb.2: |
| liveins: $nzcv, $w0 |
| ; CHECK: csel x16, x16, xzr, lt |
| RET undef $lr, implicit $w0 |
| ... |
| --- |
| name: condbranch_uncondbranch |
| tracksRegLiveness: true |
| body: | |
| ; CHECK-LABEL: condbranch_uncondbranch |
| bb.0: |
| successors: %bb.1, %bb.2 |
| liveins: $w0, $w1 |
| $wzr = SUBSWrs renamable $w0, renamable $w1, 0, implicit-def $nzcv, implicit-def $nzcv |
| Bcc 11, %bb.2, implicit $nzcv |
| B %bb.1, implicit $nzcv |
| ; CHECK: b.lt [[BB_LT_T:\.LBB[0-9_]+]] |
| |
| bb.1: |
| liveins: $nzcv, $w0 |
| ; CHECK: csel x16, x16, xzr, ge |
| RET undef $lr, implicit $w0 |
| bb.2: |
| liveins: $nzcv, $w0 |
| ; CHECK: csel x16, x16, xzr, lt |
| RET undef $lr, implicit $w0 |
| ... |
| --- |
| name: indirectbranch |
| tracksRegLiveness: true |
| body: | |
| ; Check that no instrumentation is done on indirect branches (for now). |
| ; CHECK-LABEL: indirectbranch |
| bb.0: |
| successors: %bb.1, %bb.2 |
| liveins: $x0 |
| BR $x0 |
| bb.1: |
| liveins: $x0 |
| ; CHECK-NOT: csel |
| RET undef $lr, implicit $x0 |
| bb.2: |
| liveins: $x0 |
| ; CHECK-NOT: csel |
| RET undef $lr, implicit $x0 |
| ... |