[BasicAA] Retain shl nowrap flags in GetLinearExpression()
authorNikita Popov <nikita.ppv@gmail.com>
Sat, 27 Mar 2021 11:11:25 +0000 (12:11 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Sat, 27 Mar 2021 11:26:22 +0000 (12:26 +0100)
Nowrap flags between mul and shl differ in that mul nsw allows
multiplication of 1 * INT_MIN, while shl nsw does not. This means
that it is always fine to transfer shl nowrap flags to muls, but
not necessarily the other way around. In this case the NUW/NSW
results refer to mul/add operations, so it's fine to retain the
flags from the shl.

llvm/lib/Analysis/BasicAliasAnalysis.cpp
llvm/test/Analysis/BasicAA/zext.ll

index acf7bef..6246cad 100644 (file)
@@ -314,10 +314,7 @@ static bool isObjectSize(const Value *V, uint64_t Size, const DataLayout &DL,
 
         Offset <<= RHS.getLimitedValue();
         Scale <<= RHS.getLimitedValue();
-        // the semantics of nsw and nuw for left shifts don't match those of
-        // multiplications, so we won't propagate them.
-        NSW = NUW = false;
-        return V;
+        break;
       }
 
       if (isa<OverflowingBinaryOperator>(BOp)) {
index 39e67dc..2e25734 100644 (file)
@@ -240,5 +240,29 @@ entry:
   ret float %x4
 }
 
+; CHECK-LABEL: Function: test_shl_nuw_zext
+; CHECK: MustAlias: i8* %p.1, i8* %p.2
+define void @test_shl_nuw_zext(i8* %p, i32 %x) {
+  %shl = shl nuw i32 %x, 1
+  %shl.ext = zext i32 %shl to i64
+  %ext = zext i32 %x to i64
+  %ext.shl = shl nuw i64 %ext, 1
+  %p.1 = getelementptr i8, i8* %p, i64 %shl.ext
+  %p.2 = getelementptr i8, i8* %p, i64 %ext.shl
+  ret void
+}
+
+; CHECK-LABEL: Function: test_shl_nsw_sext
+; CHECK: MustAlias: i8* %p.1, i8* %p.2
+define void @test_shl_nsw_sext(i8* %p, i32 %x) {
+  %shl = shl nsw i32 %x, 1
+  %shl.ext = sext i32 %shl to i64
+  %ext = sext i32 %x to i64
+  %ext.shl = shl nsw i64 %ext, 1
+  %p.1 = getelementptr i8, i8* %p, i64 %shl.ext
+  %p.2 = getelementptr i8, i8* %p, i64 %ext.shl
+  ret void
+}
+
 ; Function Attrs: nounwind
 declare noalias i8* @malloc(i64)