[llvm-bugs] [Bug 47927] New: Shift UB in emitLegacyZExt when "from" type is >= 64-bit

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Oct 20 15:01:11 PDT 2020


https://bugs.llvm.org/show_bug.cgi?id=47927

            Bug ID: 47927
           Summary: Shift UB in emitLegacyZExt when "from" type is >=
                    64-bit
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: DebugInfo
          Assignee: unassignedbugs at nondot.org
          Reporter: vsk at apple.com
                CC: jdevlieghere at apple.com, keith.walker at arm.com,
                    llvm-bugs at lists.llvm.org,
                    paul_robinson at playstation.sony.com

Clang trips an "out of bounds shift" UBSan diagnostic when compiling
__fixunsxfti from compiler-rt.

A reduced test:

```
; RUN: llc -filetype=obj -o - %s | llvm-dwarfdump -

define void @t(i64 %x) !dbg !6 {
  call void @llvm.dbg.value(metadata i64 %x, metadata !9,
                            metadata !DIExpression(DW_OP_LLVM_convert, 64,
DW_ATE_unsigned,
                                                   DW_OP_LLVM_convert, 128,
DW_ATE_unsigned)), !dbg !11
  ret void, !dbg !12
}

declare void @llvm.dbg.value(metadata, metadata, metadata)

!llvm.dbg.cu = !{!0}
!llvm.debugify = !{!3, !4}
!llvm.module.flags = !{!5}

!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer:
"debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug,
enums: !2)
!1 = !DIFile(filename: "legacy-zext.ll", directory: "/")
!2 = !{}
!3 = !{i64 2}
!4 = !{i64 1}
!5 = !{i64 2, !"Debug Info Version", i32 3}
!6 = distinct !DISubprogram(name: "t", linkageName: "t", scope: null, file: !1,
line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition |
DISPFlagOptimized, unit: !0, retainedNodes: !8)
!7 = !DISubroutineType(types: !2)
!8 = !{!9}
!9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
!10 = !DIBasicType(name: "ty64", size: 32, encoding: DW_ATE_unsigned)
!11 = !DILocation(line: 1, column: 1, scope: !6)
!12 = !DILocation(line: 2, column: 1, scope: !6)
```

Here's the code that trips the UBSan diagnostic:

```
void DwarfExpression::emitLegacyZExt(unsigned FromBits) {
  // (X & (1 << FromBits - 1))
  emitOp(dwarf::DW_OP_constu);
  emitUnsigned((1ULL << FromBits) - 1); //<<< HERE (FromBits >= 64)
  emitOp(dwarf::DW_OP_and);
}
```

This legacy zext operation is a fallback DW_OP_convert implementation when
targeting Dwarf 4.

One way to address the diagnostic might be to plumb APInt through
DwarfExpression, MCStreamer, MCAsmStreamer, ByteStreamer, DIEInteger and so on.
I'm not sure whether that's a direction others in the community want to go. The
complexity of the change seems somewhat out of proportion to the problem it's
trying to fix.

Is there some other way to implement the legacy zext? Or should we try not to
emit it if we can't emit the mask?

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20201020/2912088e/attachment-0001.html>


More information about the llvm-bugs mailing list