This is an archive of the discontinued LLVM Phabricator instance.

[GlobalISel] Extend booleans based on the target's BooleanContent
AbandonedPublic

Authored by mgrang on Mar 12 2018, 7:18 PM.

Details

Summary

Booleans should be extended based on the target's BooleanContent otherwise
always sign extending a 1 bit boolean results in making its value negative.

Diff Detail

Repository
rL LLVM

Event Timeline

mgrang created this revision.Mar 12 2018, 7:18 PM
mgrang added a comment.EditedMar 12 2018, 7:24 PM

Here's the failing test case:

cat a.mir
--- |
  target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
  target triple = "aarch64--"
  define void @test_constant() {
  entry:
    ret void
  }
...
---
name:            test_constant
registers:
  - { id: 0, class: _ }
body: |
  bb.0.entry:
    %0:_(s1) = G_CONSTANT i1 1
    %1:_(s32) = COPY %0(s1)
llc -O0 -run-pass=legalizer a.mir -o -

bb.0.entry:
    %2:_(s32) = G_CONSTANT i32 -1
    %0:_(s1) = G_TRUNC %2(s32)
    %1:_(s32) = COPY %0(s1)

MachineIRBuilder.cpp was the only place I could find to intercept the boolean val and zext it. Please let me know if this isn't the proper place to fix this.

arsenm added a subscriber: arsenm.Mar 12 2018, 8:25 PM
arsenm added inline comments.
lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
269–272

This depends on the TargetBooleanContents

mgrang updated this revision to Diff 138246.Mar 13 2018, 12:44 PM
mgrang edited the summary of this revision. (Show Details)

Addressed comment.

mgrang marked an inline comment as done.Mar 13 2018, 12:45 PM
mgrang retitled this revision from [GlobalISel] Zero extend booleans during legalize to [GlobalISel] Extend booleans based on the target's BooleanContent.
mgrang edited the summary of this revision. (Show Details)

This doesn't seem right.

getBooleanContents specifically describes the results and operands for a certain set of DAG operations which require values that are either true or false, but are not represented using i1 after legalization. So we're talking about the result of ISD::SETCC, the condition operand of ISD::SELECT, etc. In SelectionDAG, this set of operations are legalized using PromoteTargetBoolean. (I'm assuming GlobalISel follows similar rules, although I can't find any documentation.)

This general rule does not apply to arbitrary i1 values. When an i1 is stored to memory, it is always zero-extended. And for other operations (logic operations, PHI nodes, etc), the high bits are undefined.

Given that, messing with MachineIRBuilder::buildConstant does nothing useful: you're just hiding a bug that could be exposed by producing a boolean some other way. For example, "trunc i8 %z to i1" gets legalized to a no-op with both SelectionDAG isel and GlobalISel.

mgrang abandoned this revision.Nov 5 2018, 12:55 PM

This is fixed in D47425. Abandoning this patch.