[InstCombine] Let combineLoadToNewType preserve ABI alignment of the load (PR44543)
authorJuneyoung Lee <aqjune@gmail.com>
Tue, 14 Jan 2020 16:11:20 +0000 (01:11 +0900)
committerJuneyoung Lee <aqjune@gmail.com>
Tue, 14 Jan 2020 18:20:53 +0000 (03:20 +0900)
Summary:
If aligment on `LoadInst` isn't specified, load is assumed to be ABI-aligned.
And said aligment may be different for different types.
So if we change load type, but don't pay extra attention to the aligment
(i.e. keep it unspecified), we may either overpromise (if the default aligment
of the new type is higher), or underpromise (if the default aligment
of the new type is smaller).

Thus, if no alignment is specified, we need to manually preserve the implied ABI alignment.

This addresses https://bugs.llvm.org/show_bug.cgi?id=44543 by making combineLoadToNewType preserve ABI alignment of the load.

Reviewers: spatel, lebedev.ri

Subscribers: hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D72710

llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
llvm/test/Transforms/InstCombine/load-bitcast64.ll

index dc1ccc4bafcd212a8f88d868132bd448a639d20f..f2c2d1cdf5aeec1edad858d128db8c2900ad8b8d 100644 (file)
@@ -462,8 +462,15 @@ static LoadInst *combineLoadToNewType(InstCombiner &IC, LoadInst &LI, Type *NewT
         NewPtr->getType()->getPointerAddressSpace() == AS))
     NewPtr = IC.Builder.CreateBitCast(Ptr, NewTy->getPointerTo(AS));
 
+  unsigned Align = LI.getAlignment();
+  if (!Align)
+    // If old load did not have an explicit alignment specified,
+    // manually preserve the implied (ABI) alignment of the load.
+    // Else we may inadvertently incorrectly over-promise alignment.
+    Align = IC.getDataLayout().getABITypeAlignment(LI.getType());
+
   LoadInst *NewLoad = IC.Builder.CreateAlignedLoad(
-      NewTy, NewPtr, LI.getAlignment(), LI.isVolatile(), LI.getName() + Suffix);
+      NewTy, NewPtr, Align, LI.isVolatile(), LI.getName() + Suffix);
   NewLoad->setAtomic(LI.getOrdering(), LI.getSyncScopeID());
   copyMetadataForLoad(*NewLoad, LI);
   return NewLoad;
index 58bc923da699297dc2c4e89416cf9940ac9fa456..270bd6f5f8117ad7ed672001c302e866d685cfd4 100644 (file)
@@ -8,7 +8,7 @@ define i64* @test1(i8* %x) {
 ; CHECK-LABEL: @test1(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i8* [[X:%.*]] to i64**
-; CHECK-NEXT:    [[B1:%.*]] = load i64*, i64** [[TMP0]], align 8
+; CHECK-NEXT:    [[B1:%.*]] = load i64*, i64** [[TMP0]], align 4
 ; CHECK-NEXT:    ret i64* [[B1]]
 ;
 entry:
@@ -57,7 +57,7 @@ define i64 @test4(i8* %x) {
 ; CHECK-LABEL: @test4(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i8* [[X:%.*]] to i64*
-; CHECK-NEXT:    [[B1:%.*]] = load i64, i64* [[TMP0]], align 4
+; CHECK-NEXT:    [[B1:%.*]] = load i64, i64* [[TMP0]], align 8
 ; CHECK-NEXT:    ret i64 [[B1]]
 ;
 entry:
@@ -88,7 +88,7 @@ define i64 @test6(i8* %x) {
 ; CHECK-LABEL: @test6(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i8* [[X:%.*]] to i64*
-; CHECK-NEXT:    [[B1:%.*]] = load i64, i64* [[TMP0]], align 4
+; CHECK-NEXT:    [[B1:%.*]] = load i64, i64* [[TMP0]], align 8
 ; CHECK-NEXT:    ret i64 [[B1]]
 ;
 entry: