[PATCH] D87844: [CodeGen] Fixing inconsistent ABI mangling of vlaues in SelectionDAGBuilder

Lucas Prates via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 17 10:33:35 PDT 2020


pratlucas created this revision.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.
pratlucas requested review of this revision.

SelectionDAGBuilder was inconsistently mangling values based on ABI
Calling Conventions when getting them through copyFromRegs in
SelectionDAGBuilder, causing duplicate value type convertions for
function arguments. The checking for the mangling requirement was based
on the value's originating instruction and was performed outside of, and
inspite of, the regular Calling Convention Lowering.

The issue could be observed in a scenario such as:

  %arg1 = load half, half* %const, align 2
  %arg2 = call fastcc half @someFunc()
  call fastcc void @otherFunc(half %arg1, half %arg2)
  ; Here, %arg2 was incorrectly mangled twice, as the CallConv data from
  ; the call to @someFunc() was taken into consideration for the check
  ; when getting the value for processing the call to @otherFunc(...),
  ; after the proper convertion had taken place when lowering the return
  ; value of the first call.

This patch fixes the issue by disregarding the Calling Convention
information for such copyFromRegs, making sure the ABI mangling is
properly contanined in the Calling Convention Lowering.

This fixes Bugzilla #47454.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D87844

Files:
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/test/CodeGen/ARM/pr47454.ll


Index: llvm/test/CodeGen/ARM/pr47454.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/ARM/pr47454.ll
@@ -0,0 +1,74 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=armv8-unknown-linux-unknown -mattr=-fp16 -O0 < %s | FileCheck %s
+
+; Function Attrs: nobuiltin nounwind
+define internal fastcc half @getConstant() unnamed_addr #0 {
+Entry:
+  %result = alloca half, align 2
+  store half 0xH7C00, half* %result, align 2
+  %0 = load half, half* %result, align 2
+  ret half %0
+}
+
+; Function Attrs: nobuiltin nounwind
+define internal fastcc i1 @isEqual(half %0, half %1) unnamed_addr #0 {
+Entry:
+  %a = alloca half, align 2
+  %b = alloca half, align 2
+  store half %0, half* %a, align 2
+  store half %1, half* %b, align 2
+  %2 = load half, half* %a, align 2
+  %3 = load half, half* %b, align 2
+  %4 = fcmp une half %2, %3
+  br i1 %4, label %Then, label %Else
+Then:
+  ret i1 0
+Else:
+  ret i1 1
+}
+
+; Function Attrs: nobuiltin nounwind
+define internal fastcc void @main() unnamed_addr #0 {
+; CHECK-LABEL: main:
+; CHECK:       @ %bb.0: @ %Entry
+; CHECK-NEXT:    push {r11, lr}
+; CHECK-NEXT:    mov r11, sp
+; CHECK-NEXT:    sub sp, sp, #16
+; CHECK-NEXT:    mov r0, #31744
+; CHECK-NEXT:    strh r0, [r11, #-2]
+; CHECK-NEXT:    ldrh r0, [r11, #-2]
+; CHECK-NEXT:    bl __gnu_h2f_ieee
+; CHECK-NEXT:    vmov s0, r0
+; CHECK-NEXT:    vstr s0, [sp, #8] @ 4-byte Spill
+; CHECK-NEXT:    bl getConstant
+; CHECK-NEXT:    vmov r0, s0
+; CHECK-NEXT:    bl __gnu_h2f_ieee
+; CHECK-NEXT:    vmov s0, r0
+; CHECK-NEXT:    vmov r0, s0
+; CHECK-NEXT:    bl __gnu_f2h_ieee
+; CHECK-NEXT:    vldr s0, [sp, #8] @ 4-byte Reload
+; CHECK-NEXT:    vmov r1, s0
+; CHECK-NEXT:    str r0, [sp, #4] @ 4-byte Spill
+; CHECK-NEXT:    mov r0, r1
+; CHECK-NEXT:    bl __gnu_f2h_ieee
+; CHECK-NEXT:    uxth r0, r0
+; CHECK-NEXT:    vmov s0, r0
+; CHECK-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
+; CHECK-NEXT:    uxth r1, r0
+; CHECK-NEXT:    vmov s1, r1
+; CHECK-NEXT:    bl isEqual
+; CHECK-NEXT:    mov sp, r11
+; CHECK-NEXT:    pop {r11, pc}
+Entry:
+    ; First arg directly from constant
+    %const = alloca half, align 2
+    store half 0xH7C00, half* %const, align 2
+    %arg1 = load half, half* %const, align 2
+    ; Second arg from fucntion return
+    %arg2 = call fastcc half @getConstant()
+    ; Arguments should have equivalent mangling
+    %result = call fastcc i1 @isEqual(half %arg1, half %arg2)
+    ret void
+}
+
+attributes #0 = { nobuiltin nounwind "frame-pointer"="all" }
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1587,7 +1587,7 @@
     unsigned InReg = FuncInfo.InitializeRegForValue(Inst);
 
     RegsForValue RFV(*DAG.getContext(), TLI, DAG.getDataLayout(), InReg,
-                     Inst->getType(), getABIRegCopyCC(V));
+                     Inst->getType(), None);
     SDValue Chain = DAG.getEntryNode();
     return RFV.getCopyFromRegs(DAG, FuncInfo, getCurSDLoc(), Chain, nullptr, V);
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D87844.292561.patch
Type: text/x-patch
Size: 3241 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200917/6209b950/attachment.bin>


More information about the llvm-commits mailing list