Skip to content

[LoopVectorize] Miscompilation at -Os #149347

@dtcxzyw

Description

@dtcxzyw

Reproducer: https://alive2.llvm.org/ce/z/gVth4Q

; bin/opt -passes=loop-vectorize test.ll -S
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@g_126 = global i32 0

define i1 @src() {
entry:
  br label %for.cond232.preheader.i.i.i.i

for.cond232.preheader.i.i.i.i:                    ; preds = %safe_mod_func_uint32_t_u_u.exit.i.i.i.i, %entry
  %storemerge552.i.i.i.i = phi i16 [ 0, %entry ], [ %add302.i.i.i.i, %safe_mod_func_uint32_t_u_u.exit.i.i.i.i ]
  br i1 true, label %safe_mod_func_uint32_t_u_u.exit.i.i.i.i, label %cond.false.i518.i.i.i.i

cond.false.i518.i.i.i.i:                          ; preds = %for.cond232.preheader.i.i.i.i
  br label %safe_mod_func_uint32_t_u_u.exit.i.i.i.i

safe_mod_func_uint32_t_u_u.exit.i.i.i.i:          ; preds = %cond.false.i518.i.i.i.i, %for.cond232.preheader.i.i.i.i
  %cond.i519.i.i.i.i = phi i32 [ 0, %cond.false.i518.i.i.i.i ], [ 1, %for.cond232.preheader.i.i.i.i ]
  store i32 %cond.i519.i.i.i.i, ptr @g_126, align 4
  %add302.i.i.i.i = add i16 %storemerge552.i.i.i.i, 1
  %exitcond559.not.i.i.i.i = icmp eq i16 %add302.i.i.i.i, 3
  br i1 %exitcond559.not.i.i.i.i, label %for.inc309.i.i.i.i, label %for.cond232.preheader.i.i.i.i

for.inc309.i.i.i.i:                               ; preds = %safe_mod_func_uint32_t_u_u.exit.i.i.i.i
  %0 = load i32, ptr @g_126, align 4
  %tobool205.not.i.i.i.i = icmp eq i32 %0, 0
  ret i1 %tobool205.not.i.i.i.i
}

Output:

define i1 @src() {
entry:
  br i1 false, label %scalar.ph, label %vector.ph

vector.ph:                                        ; preds = %entry
  br label %vector.body

vector.body:                                      ; preds = %vector.ph
  store i32 0, ptr @g_126, align 4
  br label %middle.block

middle.block:                                     ; preds = %vector.body
  br label %for.inc309.i.i.i.i

scalar.ph:                                        ; preds = %entry
  %bc.resume.val = phi i16 [ 0, %entry ]
  br label %for.cond232.preheader.i.i.i.i

for.cond232.preheader.i.i.i.i:                    ; preds = %scalar.ph, %safe_mod_func_uint32_t_u_u.exit.i.i.i.i
  %storemerge552.i.i.i.i = phi i16 [ %bc.resume.val, %scalar.ph ], [ %add302.i.i.i.i, %safe_mod_func_uint32_t_u_u.exit.i.i.i.i ]
  br i1 true, label %safe_mod_func_uint32_t_u_u.exit.i.i.i.i, label %cond.false.i518.i.i.i.i

cond.false.i518.i.i.i.i:                          ; preds = %for.cond232.preheader.i.i.i.i
  br label %safe_mod_func_uint32_t_u_u.exit.i.i.i.i

safe_mod_func_uint32_t_u_u.exit.i.i.i.i:          ; preds = %cond.false.i518.i.i.i.i, %for.cond232.preheader.i.i.i.i
  %cond.i519.i.i.i.i = phi i32 [ 0, %cond.false.i518.i.i.i.i ], [ 1, %for.cond232.preheader.i.i.i.i ]
  store i32 %cond.i519.i.i.i.i, ptr @g_126, align 4
  %add302.i.i.i.i = add i16 %storemerge552.i.i.i.i, 1
  %exitcond559.not.i.i.i.i = icmp eq i16 %add302.i.i.i.i, 3
  br i1 %exitcond559.not.i.i.i.i, label %for.inc309.i.i.i.i, label %for.cond232.preheader.i.i.i.i, !llvm.loop !0

for.inc309.i.i.i.i:                               ; preds = %middle.block, %safe_mod_func_uint32_t_u_u.exit.i.i.i.i
  %0 = load i32, ptr @g_126, align 4
  %tobool205.not.i.i.i.i = icmp eq i32 %0, 0
  ret i1 %tobool205.not.i.i.i.i
}

!0 = distinct !{!0, !1, !2}
!1 = !{!"llvm.loop.unroll.runtime.disable"}
!2 = !{!"llvm.loop.isvectorized", i32 1}

Transformation doesn't verify!

ERROR: Value mismatch

Example:

Source:
  >> Jump to %for.cond232.preheader.i.i.i.i
i16 %storemerge552.i.i.i.i = #x0000 (0)
  >> Jump to %safe_mod_func_uint32_t_u_u.exit.i.i.i.i
i32 %cond.i519.i.i.i.i = #x00000001 (1)
i16 %add302.i.i.i.i = #x0001 (1)
i1 %exitcond559.not.i.i.i.i = #x0 (0)
  >> Jump to %for.cond232.preheader.i.i.i.i#2
i16 %storemerge552.i.i.i.i#2 = #x0001 (1)
  >> Jump to %safe_mod_func_uint32_t_u_u.exit.i.i.i.i#2
i32 %cond.i519.i.i.i.i#2 = #x00000001 (1)
i16 %add302.i.i.i.i#2 = #x0002 (2)
i1 %exitcond559.not.i.i.i.i#2 = #x0 (0)
  >> Jump to %for.cond232.preheader.i.i.i.i#3
i16 %storemerge552.i.i.i.i#3 = #x0002 (2)
  >> Jump to %safe_mod_func_uint32_t_u_u.exit.i.i.i.i#3
i32 %cond.i519.i.i.i.i#3 = #x00000001 (1)
i16 %add302.i.i.i.i#3 = #x0003 (3)
i1 %exitcond559.not.i.i.i.i#3 = #x1 (1)
  >> Jump to %for.inc309.i.i.i.i
i32 %#0 = #x00000001 (1)
i1 %tobool205.not.i.i.i.i = #x0 (0)

SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 >	size: 4	align: 4	alloc type: 0	alive: true	address: 4
Contents:
poison


Target:
  >> Jump to %vector.ph
  >> Jump to %vector.body
  >> Jump to %middle.block
  >> Jump to %for.inc309.i.i.i.i
i32 %#0 = #x00000000 (0)
i1 %tobool205.not.i.i.i.i = #x1 (1)
Source value: #x0 (0)
Target value: #x1 (1)

llvm version: 4bf82ae

Log before LoopVectorize:

Entering function main
  br label %for.cond232.preheader.i.i.i.i jump to %for.cond232.preheader.i.i.i.i
    phi i16 %storemerge552.i.i.i.i -> i16 0
  br i1 true, label %safe_mod_func_uint32_t_u_u.exit.i.i.i.i, label %cond.false.i518.i.i.i.i jump to %safe_mod_func_uint32_t_u_u.exit.i.i.i.i
    phi i32 %cond.i519.i.i.i.i -> i32 1
  store i32 %cond.i519.i.i.i.i, ptr @g_126, align 4
  %add302.i.i.i.i = add i16 %storemerge552.i.i.i.i, 1 -> i16 1
  %exitcond559.not.i.i.i.i = icmp eq i16 %add302.i.i.i.i, 3 -> F
  br i1 %exitcond559.not.i.i.i.i, label %for.inc309.i.i.i.i, label %for.cond232.preheader.i.i.i.i jump to %for.cond232.preheader.i.i.i.i
    phi i16 %storemerge552.i.i.i.i -> i16 1
  br i1 true, label %safe_mod_func_uint32_t_u_u.exit.i.i.i.i, label %cond.false.i518.i.i.i.i jump to %safe_mod_func_uint32_t_u_u.exit.i.i.i.i
    phi i32 %cond.i519.i.i.i.i -> i32 1
  store i32 %cond.i519.i.i.i.i, ptr @g_126, align 4
  %add302.i.i.i.i = add i16 %storemerge552.i.i.i.i, 1 -> i16 2
  %exitcond559.not.i.i.i.i = icmp eq i16 %add302.i.i.i.i, 3 -> F
  br i1 %exitcond559.not.i.i.i.i, label %for.inc309.i.i.i.i, label %for.cond232.preheader.i.i.i.i jump to %for.cond232.preheader.i.i.i.i
    phi i16 %storemerge552.i.i.i.i -> i16 2
  br i1 true, label %safe_mod_func_uint32_t_u_u.exit.i.i.i.i, label %cond.false.i518.i.i.i.i jump to %safe_mod_func_uint32_t_u_u.exit.i.i.i.i
    phi i32 %cond.i519.i.i.i.i -> i32 1
  store i32 %cond.i519.i.i.i.i, ptr @g_126, align 4
  %add302.i.i.i.i = add i16 %storemerge552.i.i.i.i, 1 -> i16 3
  %exitcond559.not.i.i.i.i = icmp eq i16 %add302.i.i.i.i, 3 -> T
  br i1 %exitcond559.not.i.i.i.i, label %for.inc309.i.i.i.i, label %for.cond232.preheader.i.i.i.i jump to %for.inc309.i.i.i.i
  %0 = load i32, ptr @g_126, align 4 -> i32 1
  %tobool205.not.i.i.i.i = icmp eq i32 %0, 0 -> F
  ret i1 %tobool205.not.i.i.i.i
Exiting function main

After LoopVectorize:

Entering function main
  br i1 false, label %scalar.ph, label %vector.ph jump to %vector.ph
  br label %vector.body jump to %vector.body
  store i32 0, ptr @g_126, align 4
  br label %middle.block jump to %middle.block
  br label %for.inc309.i.i.i.i jump to %for.inc309.i.i.i.i
  %0 = load i32, ptr @g_126, align 4 -> i32 0
  %tobool205.not.i.i.i.i = icmp eq i32 %0, 0 -> T
  ret i1 %tobool205.not.i.i.i.i
Exiting function main

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions