[PATCH] D108734: [InstCombine] Replace icmp invariant group operands with the invariant group's operands

Piotr Padlewski via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 26 05:30:36 PDT 2021


Prazek requested changes to this revision.
Prazek added a comment.
This revision now requires changes to proceed.

Lets talk offline about the specific case to get it right.  The model is pretty brittle in those areas, so we have to be sure the transformations are legal



================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp:5705-5717
+static Instruction *foldICmpInvariantGroup(ICmpInst &I) {
+  std::array<Value *, 2> Ops = {I.getOperand(0), I.getOperand(1)};
+  bool Changed = false;
+  for (Value *&Op : Ops) {
+    auto *I = dyn_cast<Instruction>(Op);
+    if (!I || !I->isLaunderOrStripInvariantGroup())
+      continue;
----------------
If I understand this correctly, this essentially strips launders/strips from cmp operands.

I think this is incorrect. From the perspective of devirtualization we can have code like:


  %vtable_a = load i8* %a, !invariant.group !{}
  ;;;
  ; %a == %b
  %addr_a = call i8* @llvm.strip.invariant.group(i8* %a)
  %addr_b = call i8* @llvm.strip.invariant.group(i8* %b)
  %bool = icmp %addr_a, %addr_b
  br %bool, %if, %after
  if:
  ; This will not be able to change %b to %a
  %vtable_b = load i8* %b, !invariant.group !{}


As you see, the two loads operate on %a and %b (where %b is a result of launder). As comparisons can leak the idea that %a and %b are essentially the same addresses (thus enabling GVN to RAUW %b with %a), we need to strip it before cmp. 

In this case, we would replace the cmp with icmp %a %b, which would essentially tell GVN %a and %b can be used interchanganbly in this branch.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D108734/new/

https://reviews.llvm.org/D108734



More information about the llvm-commits mailing list