Commit 2d9759c7 authored by Shimin Cui's avatar Shimin Cui
Browse files

[GlobalOpt] Fix the load types when OptimizeGlobalAddressOfMalloc

Currently, in OptimizeGlobalAddressOfMalloc, the transformation for global loads assumes that they have the same Type. With the support of ConstantExpr (https://reviews.llvm.org/D106589), this may not be true any more (as seen in the test case), and we miss the code to handle this, This is to fix that.

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D107397
parent ba2be8de
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -967,9 +967,8 @@ OptimizeGlobalAddressOfMalloc(GlobalVariable *GV, CallInst *CI, Type *AllocTy,
    }
  }

  Constant *RepValue = NewGV;
  if (NewGV->getType() != GV->getValueType())
    RepValue = ConstantExpr::getBitCast(RepValue, GV->getValueType());
  SmallPtrSet<Constant *, 1> RepValues;
  RepValues.insert(NewGV);

  // If there is a comparison against null, we will insert a global bool to
  // keep track of whether the global was initialized yet or not.
@@ -1001,7 +1000,9 @@ OptimizeGlobalAddressOfMalloc(GlobalVariable *GV, CallInst *CI, Type *AllocTy,
      Use &LoadUse = *LI->use_begin();
      ICmpInst *ICI = dyn_cast<ICmpInst>(LoadUse.getUser());
      if (!ICI) {
        LoadUse = RepValue;
        auto *CE = ConstantExpr::getBitCast(NewGV, LI->getType());
        RepValues.insert(CE);
        LoadUse.set(CE);
        continue;
      }

@@ -1047,9 +1048,8 @@ OptimizeGlobalAddressOfMalloc(GlobalVariable *GV, CallInst *CI, Type *AllocTy,
  // To further other optimizations, loop over all users of NewGV and try to
  // constant prop them.  This will promote GEP instructions with constant
  // indices into GEP constant-exprs, which will allow global-opt to hack on it.
  ConstantPropUsersOf(NewGV, DL, TLI);
  if (RepValue != NewGV)
    ConstantPropUsersOf(RepValue, DL, TLI);
  for (auto *CE : RepValues)
    ConstantPropUsersOf(CE, DL, TLI);

  return NewGV;
}
+44 −0
Original line number Diff line number Diff line
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -globalopt -S < %s | FileCheck %s
; RUN: opt -passes=globalopt -S < %s | FileCheck %s

@g = internal global i32* null, align 8

define signext i32 @f() local_unnamed_addr {
; CHECK-LABEL: @f(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    call void @f1()
; CHECK-NEXT:    store i32 1, i32* @g.body, align 4
; CHECK-NEXT:    call void @f1()
; CHECK-NEXT:    store i8 2, i8* bitcast (i32* @g.body to i8*), align 4
; CHECK-NEXT:    ret i32 1
;
entry:
  %call = call i8* @malloc(i64 4)
  %b = bitcast i8* %call to i32*
  store i32* %b, i32** @g, align 8
  call void @f1()
  %0 = load i32*, i32** @g, align 8
  store i32 1, i32* %0, align 4
  call void @f1()
  %1 = load i8*, i8** bitcast (i32** @g to i8**), align 8
  store i8 2, i8* %1, align 4
  ret i32 1
}

define signext i32 @main() {
; CHECK-LABEL: @main(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[CALL:%.*]] = call signext i32 @f()
; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* @g.body, align 4
; CHECK-NEXT:    ret i32 [[TMP0]]
;
entry:
  %call = call signext i32 @f()
  %0 = load i32*, i32** @g, align 8
  %1 = load i32, i32* %0, align 4
  ret i32 %1
}

declare noalias align 16 i8* @malloc(i64)
declare void @f1()