brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.6 KiB · cb74ae6 Raw
130 lines · plain
1; RUN: llc -mtriple x86_64-apple-darwin -O0 < %s -o - | FileCheck %s2;3; During X86 fastisel, the address of indirect call was resolved4; through bitcast, ptrtoint, and inttoptr instructions. This is valid5; only if the related instructions are in that same basic block, otherwise6; we may reference variables that were not live across basic blocks7; resulting in undefined virtual registers.8;9; In this example, this is illustrated by a spill/reload of the10; LOADED_PTR_SLOT.11;12; Before this patch, the compiler was accessing two different spill13; slots.14; <rdar://problem/15192473>15 16; CHECK-LABEL: @test_bitcast17; Load the value of the function pointer: %loaded_ptr18; Spill %arg2.19; CHECK: movq %rdx, [[ARG2_SLOT:[0-9]*\(%[a-z]+\)]]20; CHECK: movq (%rdi), [[LOADED_PTR:%[a-z]+]]21; Spill %loaded_ptr.22; CHECK: movq [[LOADED_PTR]], [[LOADED_PTR_SLOT:[0-9]*\(%[a-z]+\)]]23; Perform the indirect call.24; Load the function pointer.25; CHECK: movq [[LOADED_PTR_SLOT]], [[FCT_PTR:%[a-z]+]]26; Load the third argument27; CHECK: movq [[ARG2_SLOT]], %rdx28; Load the first argument29; CHECK: movq %rdx, %rdi30; Load the second argument31; CHECK: movq %rdx, %rsi32; Call.33; CHECK: callq *[[FCT_PTR]]34; CHECK: ret35define i64 @test_bitcast(ptr %arg, i1 %bool, i64 %arg2) {36entry:37  %loaded_ptr = load ptr, ptr %arg, align 838  switch i1 %bool, label %default [39    i1 true, label %label_true40    i1 false, label %label_end41  ]42default:43  br label %label_end44 45label_true:46  br label %label_end47 48label_end:49  %res = call i64 %loaded_ptr(i64 %arg2, i64 %arg2, i64 %arg2)50  ret i64 %res51}52 53; CHECK-LABEL: @test_inttoptr54; Load the value of the function pointer: %loaded_ptr55; CHECK: movq %rdx, [[ARG2_SLOT:[0-9]*\(%[a-z]+\)]]56; Spill %loaded_ptr.57; CHECK: movq (%rdi), [[LOADED_PTR:%[a-z]+]]58; Spill %arg2.59; CHECK: movq [[LOADED_PTR]], [[LOADED_PTR_SLOT:[0-9]*\(%[a-z]+\)]]60; Perform the indirect call.61; Load the function pointer.62; CHECK: movq [[LOADED_PTR_SLOT]], [[FCT_PTR:%[a-z]+]]63; Load the third argument64; CHECK: movq [[ARG2_SLOT]], %rdx65; Load the first argument66; CHECK: movq %rdx, %rdi67; Load the second argument68; CHECK: movq %rdx, %rsi69; Call.70; CHECK: callq *[[FCT_PTR]]71; CHECK: ret72define i64 @test_inttoptr(ptr %arg, i1 %bool, i64 %arg2) {73entry:74  %loaded_ptr = load ptr, ptr %arg, align 875  %raw = ptrtoint ptr %loaded_ptr to i6476  switch i1 %bool, label %default [77    i1 true, label %label_true78    i1 false, label %label_end79  ]80default:81  br label %label_end82 83label_true:84  br label %label_end85 86label_end:87  %fct_ptr = inttoptr i64 %raw to ptr88  %res = call i64 %fct_ptr(i64 %arg2, i64 %arg2, i64 %arg2)89  ret i64 %res90}91 92; CHECK-LABEL: @test_ptrtoint93; Spill %arg2.94; CHECK: movq %rdx, [[ARG2_SLOT:[0-9]*\(%[a-z]+\)]]95; Load the value of the function pointer: %loaded_ptr96; CHECK: movq (%rdi), [[LOADED_PTR:%[a-z]+]]97; Spill %loaded_ptr.98; CHECK: movq [[LOADED_PTR]], [[LOADED_PTR_SLOT:[0-9]*\(%[a-z]+\)]]99; Perform the indirect call.100; Load the function pointer.101; CHECK: movq [[LOADED_PTR_SLOT]], [[FCT_PTR:%[a-z]+]]102; Load the third argument103; CHECK: movq [[ARG2_SLOT]], %rdx104; Load the first argument105; CHECK: movq %rdx, %rdi106; Load the second argument107; CHECK: movq %rdx, %rsi108; Call.109; CHECK: callq *[[FCT_PTR]]110; CHECK: ret111define i64 @test_ptrtoint(ptr %arg, i1 %bool, i64 %arg2) {112entry:113  %loaded_ptr = load ptr, ptr %arg, align 8114  switch i1 %bool, label %default [115    i1 true, label %label_true116    i1 false, label %label_end117  ]118default:119  br label %label_end120 121label_true:122  br label %label_end123 124label_end:125  %fct_int = ptrtoint ptr %loaded_ptr to i64126  %fct_ptr = inttoptr i64 %fct_int to ptr127  %res = call i64 %fct_ptr(i64 %arg2, i64 %arg2, i64 %arg2)128  ret i64 %res129}130